mongo_cache_store 0.2.3 → 0.2.4
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.
- checksums.yaml +7 -0
- data/README.rdoc +20 -1
- data/lib/active_support/cache/mongo_cache_store.rb +1 -1
- data/lib/active_support/cache/mongo_cache_store/backend/base.rb +107 -13
- data/lib/mongo_cache_store/version.rb +1 -1
- data/mongo_cache_store.gemspec +1 -0
- data/test/abstract_unit.rb +64 -0
- data/test/multi_ttl_test.rb +24 -0
- data/test/standard_test.rb +24 -0
- data/test/test_modules.rb +388 -0
- data/test/ttl_test.rb +24 -0
- metadata +35 -23
- data/spec/active_support/cache/mongo_cache_store_spec.rb +0 -179
- data/spec/spec_helper.rb +0 -6
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 00920d89d10ee3956b56d6de55b5bdd9c93a54db
|
4
|
+
data.tar.gz: 09a537ab5771d079419f9a4506a65001e0a125e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 58456d15add616876bfd56b98e42a129379412799f8b6576e2a40c51a7e7f1860a8e16f34b8106a0f2c034ed9270ba25da11e0e9b9be2f78ceafcb88d8ae936a
|
7
|
+
data.tar.gz: 889281aeedcbfab621b5811e3141bef5e5ae877b6b7a71aca26de07a7ce4eac3d2fc973f7d8e8cb17dce32dd6afa09c41249d93f04099eafaa10a98be7b9b175
|
data/README.rdoc
CHANGED
@@ -56,6 +56,25 @@ configured or used.
|
|
56
56
|
Useful for write conditions and read preferences
|
57
57
|
|
58
58
|
|
59
|
+
== Increment / Decrement
|
60
|
+
|
61
|
+
Increment and decrement values must be an Integer. In the ActiveSupport test
|
62
|
+
suite strings and integers are used interchangeably. This cache store however
|
63
|
+
uses MongoDB's $inc operator which must, be an integer.
|
64
|
+
|
65
|
+
|
66
|
+
== Keys can be a Hash
|
67
|
+
|
68
|
+
The following test from ActiveSupport fails with MongoCacheStore:
|
69
|
+
|
70
|
+
def test_hash_as_cache_key
|
71
|
+
@cache.write({:foo => 1, :fu => 2}, "bar")
|
72
|
+
assert_equal "bar", @cache.read("foo=1/fu=2")
|
73
|
+
end
|
74
|
+
|
75
|
+
This is because a key can be a true Hash. It will not be converted to a string.
|
76
|
+
|
77
|
+
|
59
78
|
== Backends
|
60
79
|
|
61
80
|
== TTL
|
@@ -67,7 +86,7 @@ TTL backend for MongoCacheStore
|
|
67
86
|
Entries are kept in a namespaced TTL collection that will
|
68
87
|
automatically flush any entries as they pass their expiration
|
69
88
|
time. This keeps the size of the cache in check over time.
|
70
|
-
<b>Requires MongoDB 2.
|
89
|
+
<b>Requires MongoDB 2.2 or higher</b>
|
71
90
|
|
72
91
|
=== Additional Options
|
73
92
|
|
@@ -7,15 +7,70 @@ module ActiveSupport
|
|
7
7
|
# Base methods used by all MongoCacheStore backends
|
8
8
|
module Base
|
9
9
|
|
10
|
-
|
10
|
+
|
11
|
+
def increment(name, amount = 1, options = {})
|
12
|
+
write_counter(name,amount.to_i,options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def decrement(name, amount = 1, options = {})
|
16
|
+
write_counter(name,amount.to_i*-1,options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_multi(*names)
|
20
|
+
options = names.extract_options!
|
21
|
+
options = merged_options(options)
|
22
|
+
results = {}
|
23
|
+
|
24
|
+
col = get_collection(options)
|
25
|
+
|
26
|
+
key_map = names.inject({}) do |h, name|
|
27
|
+
h[namespaced_key(name,options)] = name
|
28
|
+
h
|
29
|
+
end
|
30
|
+
|
31
|
+
safe_rescue do
|
32
|
+
query = {
|
33
|
+
:_id => { '$in' => key_map.keys},
|
34
|
+
:expires_at => {
|
35
|
+
'$gt' => Time.now
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
col.find(query) do |cursor|
|
40
|
+
cursor.each do |r|
|
41
|
+
results[key_map[r['_id']]] = inflate_entry(r).value
|
42
|
+
puts results.inspect
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
results
|
48
|
+
end
|
11
49
|
|
12
50
|
private
|
13
51
|
|
14
|
-
def
|
15
|
-
return key
|
52
|
+
def expanded_key(key)
|
53
|
+
return key.cache_key.to_s if key.respond_to?(:cache_key)
|
54
|
+
|
55
|
+
case key
|
56
|
+
when Array
|
57
|
+
if key.size > 1
|
58
|
+
key = key.collect{|element| expanded_key(element)}
|
59
|
+
else
|
60
|
+
key = key.first
|
61
|
+
end
|
62
|
+
when Hash
|
63
|
+
return key
|
64
|
+
end
|
65
|
+
|
66
|
+
key.to_param
|
16
67
|
end
|
17
68
|
|
18
69
|
def namespaced_key(key, options)
|
70
|
+
key = expanded_key(key)
|
71
|
+
key = key.join('/') if key.is_a?(Array)
|
72
|
+
key = key.cache_key if key.methods.include?(:cache_key)
|
73
|
+
|
19
74
|
return key
|
20
75
|
end
|
21
76
|
|
@@ -31,25 +86,62 @@ module ActiveSupport
|
|
31
86
|
}
|
32
87
|
|
33
88
|
response = col.find_one(query)
|
34
|
-
return
|
89
|
+
return inflate_entry(response)
|
90
|
+
end
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def inflate_entry(from_mongo)
|
96
|
+
return nil if from_mongo.nil?
|
35
97
|
|
36
98
|
entry_options = {
|
37
|
-
:compressed =>
|
38
|
-
:expires_in =>
|
99
|
+
:compressed => from_mongo['compressed'],
|
100
|
+
:expires_in => from_mongo['expires_in']
|
39
101
|
}
|
40
|
-
if
|
41
|
-
r_value =
|
102
|
+
if from_mongo['serialized']
|
103
|
+
r_value = from_mongo['value'].to_s
|
42
104
|
else
|
43
|
-
r_value = Marshal.dump(
|
105
|
+
r_value = Marshal.dump(from_mongo['value'])
|
44
106
|
end
|
45
|
-
ActiveSupport::Cache::Entry.create(r_value,
|
46
|
-
end
|
107
|
+
ActiveSupport::Cache::Entry.create(r_value,from_mongo['created_at'],entry_options)
|
47
108
|
end
|
48
109
|
|
110
|
+
def write_counter(name, amount, options)
|
111
|
+
col = get_collection(options)
|
112
|
+
key = namespaced_key(name,options)
|
113
|
+
|
114
|
+
safe_rescue do
|
115
|
+
doc = col.find_and_modify(
|
116
|
+
:query => {
|
117
|
+
:_id => key
|
118
|
+
},
|
119
|
+
:update => {
|
120
|
+
:$inc => {
|
121
|
+
:value => amount
|
122
|
+
}
|
123
|
+
}
|
124
|
+
)
|
125
|
+
|
126
|
+
doc['value'] + amount
|
127
|
+
end
|
128
|
+
end
|
49
129
|
|
50
130
|
def write_entry(key,entry,options)
|
51
131
|
col = get_collection(options)
|
52
132
|
serialize = options[:serialize] == :always ? true : false
|
133
|
+
serialize = false if entry.value.is_a?(Integer) || entry.value.nil?
|
134
|
+
|
135
|
+
value = begin
|
136
|
+
if entry.compressed?
|
137
|
+
BSON::Binary.new(entry.raw_value)
|
138
|
+
elsif serialize
|
139
|
+
BSON::Binary.new(entry.raw_value)
|
140
|
+
else
|
141
|
+
entry.value
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
53
145
|
try_cnt = 0
|
54
146
|
|
55
147
|
save_doc = {
|
@@ -59,7 +151,7 @@ module ActiveSupport
|
|
59
151
|
:expires_at => entry.expires_in.nil? ? Time.utc(9999) : Time.at(entry.expires_at),
|
60
152
|
:compressed => entry.compressed?,
|
61
153
|
:serialized => serialize,
|
62
|
-
:value
|
154
|
+
:value => value
|
63
155
|
}.merge(options[:xentry] || {})
|
64
156
|
|
65
157
|
safe_rescue do
|
@@ -74,8 +166,10 @@ module ActiveSupport
|
|
74
166
|
end
|
75
167
|
end
|
76
168
|
end
|
169
|
+
|
77
170
|
end
|
78
171
|
|
172
|
+
|
79
173
|
def delete_entry(key,options)
|
80
174
|
col = get_collection(options)
|
81
175
|
safe_rescue do
|
@@ -86,7 +180,7 @@ module ActiveSupport
|
|
86
180
|
def get_collection_name(options = {})
|
87
181
|
name_parts = ['cache']
|
88
182
|
name_parts.push(backend_name)
|
89
|
-
name_parts.push options[:namespace]
|
183
|
+
name_parts.push options[:namespace] if !options[:namespace].nil?
|
90
184
|
name = name_parts.join('.')
|
91
185
|
return name
|
92
186
|
end
|
data/mongo_cache_store.gemspec
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
ORIG_ARGV = ARGV.dup
|
2
|
+
|
3
|
+
#begin
|
4
|
+
# old, $VERBOSE = $VERBOSE, nil
|
5
|
+
# require File.expand_path('../../../load_paths', __FILE__)
|
6
|
+
#ensure
|
7
|
+
# $VERBOSE = old
|
8
|
+
#end
|
9
|
+
|
10
|
+
lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
11
|
+
$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
12
|
+
|
13
|
+
require 'active_support/core_ext/kernel/reporting'
|
14
|
+
|
15
|
+
require 'active_support/core_ext/string/encoding'
|
16
|
+
if "ruby".encoding_aware?
|
17
|
+
# These are the normal settings that will be set up by Railties
|
18
|
+
# TODO: Have these tests support other combinations of these values
|
19
|
+
silence_warnings do
|
20
|
+
Encoding.default_internal = "UTF-8"
|
21
|
+
Encoding.default_external = "UTF-8"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'test/unit'
|
26
|
+
#require 'empty_bool'
|
27
|
+
|
28
|
+
silence_warnings { require 'mocha' }
|
29
|
+
|
30
|
+
ENV['NO_RELOAD'] = '1'
|
31
|
+
require 'active_support'
|
32
|
+
|
33
|
+
# Include shims until we get off 1.8.6
|
34
|
+
require 'active_support/ruby/shim' if RUBY_VERSION < '1.8.7'
|
35
|
+
|
36
|
+
def uses_memcached(test_name)
|
37
|
+
require 'memcache'
|
38
|
+
begin
|
39
|
+
MemCache.new('localhost:11211').stats
|
40
|
+
yield
|
41
|
+
rescue MemCache::MemCacheError
|
42
|
+
$stderr.puts "Skipping #{test_name} tests. Start memcached and try again."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def with_kcode(code)
|
47
|
+
if RUBY_VERSION < '1.9'
|
48
|
+
begin
|
49
|
+
old_kcode, $KCODE = $KCODE, code
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
$KCODE = old_kcode
|
53
|
+
end
|
54
|
+
else
|
55
|
+
yield
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Show backtraces for deprecated behavior for quicker cleanup.
|
60
|
+
ActiveSupport::Deprecation.debug = true
|
61
|
+
|
62
|
+
if RUBY_VERSION < '1.9'
|
63
|
+
$KCODE = 'UTF8'
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'abstract_unit'
|
2
|
+
require 'mongo'
|
3
|
+
require 'active_support/test_case'
|
4
|
+
require 'active_support/cache'
|
5
|
+
require_relative 'test_modules'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
class MongoCacheStoreTTLTest < ActiveSupport::TestCase
|
10
|
+
def setup
|
11
|
+
@cache = ActiveSupport::Cache.lookup_store(
|
12
|
+
:mongo_cache_store, :TTL,
|
13
|
+
:db => Mongo::DB.new('db_name',Mongo::Connection.new),
|
14
|
+
:expires_in => 60
|
15
|
+
)
|
16
|
+
@cache.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
include CacheStoreBehavior
|
20
|
+
# include LocalCacheBehavior
|
21
|
+
include CacheIncrementDecrementBehavior
|
22
|
+
# include EncodedKeyCacheBehavior
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'abstract_unit'
|
2
|
+
require 'mongo'
|
3
|
+
require 'active_support/test_case'
|
4
|
+
require 'active_support/cache'
|
5
|
+
require_relative 'test_modules'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
class MongoCacheStoreTTLTest < ActiveSupport::TestCase
|
10
|
+
def setup
|
11
|
+
@cache = ActiveSupport::Cache.lookup_store(
|
12
|
+
:mongo_cache_store, :Standard,
|
13
|
+
:db => Mongo::DB.new('db_name',Mongo::Connection.new),
|
14
|
+
:expires_in => 60
|
15
|
+
)
|
16
|
+
@cache.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
include CacheStoreBehavior
|
20
|
+
# include LocalCacheBehavior
|
21
|
+
include CacheIncrementDecrementBehavior
|
22
|
+
# include EncodedKeyCacheBehavior
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,388 @@
|
|
1
|
+
# Tests the base functionality that should be identical across all cache stores.
|
2
|
+
|
3
|
+
module EncodedKeyCacheBehavior
|
4
|
+
if defined?(Encoding)
|
5
|
+
Encoding.list.each do |encoding|
|
6
|
+
define_method "test_#{encoding.name.underscore}_encoded_values" do
|
7
|
+
key = "foo".force_encoding(encoding)
|
8
|
+
assert @cache.write(key, 1, :raw => true)
|
9
|
+
assert_equal 1, @cache.read(key)
|
10
|
+
assert_equal 1, @cache.fetch(key)
|
11
|
+
assert @cache.delete(key)
|
12
|
+
assert_equal 2, @cache.fetch(key, :raw => true) { 2 }
|
13
|
+
assert_equal 3, @cache.increment(key)
|
14
|
+
assert_equal 2, @cache.decrement(key)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_common_utf8_values
|
19
|
+
key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
|
20
|
+
assert @cache.write(key, 1, :raw => true)
|
21
|
+
assert_equal 1, @cache.read(key)
|
22
|
+
assert_equal 1, @cache.fetch(key)
|
23
|
+
assert @cache.delete(key)
|
24
|
+
assert_equal 2, @cache.fetch(key, :raw => true) { 2 }
|
25
|
+
assert_equal 3, @cache.increment(key)
|
26
|
+
assert_equal 2, @cache.decrement(key)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_retains_encoding
|
30
|
+
key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
|
31
|
+
assert @cache.write(key, 1, :raw => true)
|
32
|
+
assert_equal Encoding::UTF_8, key.encoding
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module CacheIncrementDecrementBehavior
|
38
|
+
def test_increment
|
39
|
+
@cache.write('foo', 1, :raw => true)
|
40
|
+
assert_equal 1, @cache.read('foo').to_i
|
41
|
+
assert_equal 2, @cache.increment('foo')
|
42
|
+
assert_equal 2, @cache.read('foo').to_i
|
43
|
+
assert_equal 3, @cache.increment('foo')
|
44
|
+
assert_equal 3, @cache.read('foo').to_i
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_decrement
|
48
|
+
@cache.write('foo', 3, :raw => true)
|
49
|
+
assert_equal 3, @cache.read('foo').to_i
|
50
|
+
assert_equal 2, @cache.decrement('foo')
|
51
|
+
assert_equal 2, @cache.read('foo').to_i
|
52
|
+
assert_equal 1, @cache.decrement('foo')
|
53
|
+
assert_equal 1, @cache.read('foo').to_i
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module LocalCacheBehavior
|
58
|
+
def test_local_writes_are_persistent_on_the_remote_cache
|
59
|
+
retval = @cache.with_local_cache do
|
60
|
+
@cache.write('foo', 'bar')
|
61
|
+
end
|
62
|
+
assert retval
|
63
|
+
assert_equal 'bar', @cache.read('foo')
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_clear_also_clears_local_cache
|
67
|
+
@cache.with_local_cache do
|
68
|
+
@cache.write('foo', 'bar')
|
69
|
+
@cache.clear
|
70
|
+
assert_nil @cache.read('foo')
|
71
|
+
end
|
72
|
+
|
73
|
+
assert_nil @cache.read('foo')
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_local_cache_of_write
|
77
|
+
@cache.with_local_cache do
|
78
|
+
@cache.write('foo', 'bar')
|
79
|
+
@peek.delete('foo')
|
80
|
+
assert_equal 'bar', @cache.read('foo')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_local_cache_of_read
|
85
|
+
@cache.write('foo', 'bar')
|
86
|
+
@cache.with_local_cache do
|
87
|
+
assert_equal 'bar', @cache.read('foo')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_local_cache_of_write_nil
|
92
|
+
@cache.with_local_cache do
|
93
|
+
assert @cache.write('foo', nil)
|
94
|
+
assert_nil @cache.read('foo')
|
95
|
+
@peek.write('foo', 'bar')
|
96
|
+
assert_nil @cache.read('foo')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_local_cache_of_delete
|
101
|
+
@cache.with_local_cache do
|
102
|
+
@cache.write('foo', 'bar')
|
103
|
+
@cache.delete('foo')
|
104
|
+
assert_nil @cache.read('foo')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_local_cache_of_exist
|
109
|
+
@cache.with_local_cache do
|
110
|
+
@cache.write('foo', 'bar')
|
111
|
+
@peek.delete('foo')
|
112
|
+
assert @cache.exist?('foo')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_local_cache_of_increment
|
117
|
+
@cache.with_local_cache do
|
118
|
+
@cache.write('foo', 1, :raw => true)
|
119
|
+
@peek.write('foo', 2, :raw => true)
|
120
|
+
@cache.increment('foo')
|
121
|
+
assert_equal 3, @cache.read('foo')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_local_cache_of_decrement
|
126
|
+
@cache.with_local_cache do
|
127
|
+
@cache.write('foo', 1, :raw => true)
|
128
|
+
@peek.write('foo', 3, :raw => true)
|
129
|
+
@cache.decrement('foo')
|
130
|
+
assert_equal 2, @cache.read('foo')
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_middleware
|
135
|
+
app = lambda { |env|
|
136
|
+
result = @cache.write('foo', 'bar')
|
137
|
+
assert_equal 'bar', @cache.read('foo') # make sure 'foo' was written
|
138
|
+
assert result
|
139
|
+
}
|
140
|
+
app = @cache.middleware.new(app)
|
141
|
+
app.call({})
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
module CacheStoreBehavior
|
146
|
+
def test_should_read_and_write_strings
|
147
|
+
assert @cache.write('foo', 'bar')
|
148
|
+
assert_equal 'bar', @cache.read('foo')
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_should_overwrite
|
152
|
+
@cache.write('foo', 'bar')
|
153
|
+
@cache.write('foo', 'baz')
|
154
|
+
assert_equal 'baz', @cache.read('foo')
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_fetch_without_cache_miss
|
158
|
+
@cache.write('foo', 'bar')
|
159
|
+
@cache.expects(:write).never
|
160
|
+
assert_equal 'bar', @cache.fetch('foo') { 'baz' }
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_fetch_with_cache_miss
|
164
|
+
@cache.expects(:write).with('foo', 'baz', @cache.options)
|
165
|
+
assert_equal 'baz', @cache.fetch('foo') { 'baz' }
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_fetch_with_forced_cache_miss
|
169
|
+
@cache.write('foo', 'bar')
|
170
|
+
@cache.expects(:read).never
|
171
|
+
@cache.expects(:write).with('foo', 'bar', @cache.options.merge(:force => true))
|
172
|
+
@cache.fetch('foo', :force => true) { 'bar' }
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_fetch_with_cached_nil
|
176
|
+
@cache.write('foo', nil)
|
177
|
+
#@cache.expects(:write).never
|
178
|
+
assert_nil @cache.fetch('foo') { 'baz' }
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_should_read_and_write_hash
|
182
|
+
assert @cache.write('foo', {:a => "b"})
|
183
|
+
assert_equal({:a => "b"}, @cache.read('foo'))
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_should_read_and_write_integer
|
187
|
+
assert @cache.write('foo', 1)
|
188
|
+
assert_equal 1, @cache.read('foo')
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_should_read_and_write_nil
|
192
|
+
assert @cache.write('foo', nil)
|
193
|
+
assert_equal nil, @cache.read('foo')
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_should_read_and_write_false
|
197
|
+
assert @cache.write('foo', false)
|
198
|
+
assert_equal false, @cache.read('foo')
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_should_read_cached_numeric_from_previous_rails_versions
|
202
|
+
@old_cache = ActiveSupport::Cache::Entry.create( 1, Time.now )
|
203
|
+
assert_equal( 1, @old_cache.value )
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_should_read_cached_hash_from_previous_rails_versions
|
207
|
+
@old_cache = ActiveSupport::Cache::Entry.create( {}, Time.now )
|
208
|
+
assert_equal( {}, @old_cache.value )
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_should_read_cached_string_from_previous_rails_versions
|
212
|
+
@old_cache = ActiveSupport::Cache::Entry.create( 'string', Time.now )
|
213
|
+
assert_equal( 'string', @old_cache.value )
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_read_multi
|
217
|
+
@cache.write('foo', 'bar')
|
218
|
+
@cache.write('fu', 'baz')
|
219
|
+
@cache.write('fud', 'biz')
|
220
|
+
assert_equal({"foo" => "bar", "fu" => "baz"}, @cache.read_multi('foo', 'fu'))
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_read_multi_with_expires
|
224
|
+
@cache.write('foo', 'bar', :expires_in => 0.001)
|
225
|
+
@cache.write('fu', 'baz')
|
226
|
+
@cache.write('fud', 'biz')
|
227
|
+
sleep(0.002)
|
228
|
+
assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_read_and_write_compressed_small_data
|
232
|
+
@cache.write('foo', 'bar', :compress => true)
|
233
|
+
raw_value = @cache.send(:read_entry, 'foo', {}).raw_value
|
234
|
+
assert_equal 'bar', @cache.read('foo')
|
235
|
+
assert_equal 'bar', Marshal.load(raw_value)
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_read_and_write_compressed_large_data
|
239
|
+
@cache.write('foo', 'bar', :compress => true, :compress_threshold => 2)
|
240
|
+
raw_value = @cache.send(:read_entry, 'foo', {}).raw_value
|
241
|
+
assert_equal 'bar', @cache.read('foo')
|
242
|
+
assert_equal 'bar', Marshal.load(Zlib::Inflate.inflate(raw_value))
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_read_and_write_compressed_nil
|
246
|
+
@cache.write('foo', nil, :compress => true)
|
247
|
+
assert_nil @cache.read('foo')
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_cache_key
|
251
|
+
obj = Object.new
|
252
|
+
def obj.cache_key
|
253
|
+
:foo
|
254
|
+
end
|
255
|
+
@cache.write(obj, "bar")
|
256
|
+
assert_equal "bar", @cache.read("foo")
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_param_as_cache_key
|
260
|
+
obj = Object.new
|
261
|
+
def obj.to_param
|
262
|
+
"foo"
|
263
|
+
end
|
264
|
+
@cache.write(obj, "bar")
|
265
|
+
assert_equal "bar", @cache.read("foo")
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_array_as_cache_key
|
269
|
+
@cache.write([:fu, "foo"], "bar")
|
270
|
+
assert_equal "bar", @cache.read("fu/foo")
|
271
|
+
end
|
272
|
+
|
273
|
+
def test_hash_as_cache_key
|
274
|
+
@cache.write({:foo => 1, :fu => 2}, "bar")
|
275
|
+
assert_equal "bar", @cache.read({:foo => 1, :fu => 2})
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_keys_are_case_sensitive
|
279
|
+
@cache.write("foo", "bar")
|
280
|
+
assert_nil @cache.read("FOO")
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_exist
|
284
|
+
@cache.write('foo', 'bar')
|
285
|
+
assert @cache.exist?('foo')
|
286
|
+
assert !@cache.exist?('bar')
|
287
|
+
end
|
288
|
+
|
289
|
+
def test_nil_exist
|
290
|
+
@cache.write('foo', nil)
|
291
|
+
assert @cache.exist?('foo')
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_delete
|
295
|
+
@cache.write('foo', 'bar')
|
296
|
+
assert @cache.exist?('foo')
|
297
|
+
assert @cache.delete('foo')
|
298
|
+
assert !@cache.exist?('foo')
|
299
|
+
end
|
300
|
+
|
301
|
+
def test_read_should_return_a_different_object_id_each_time_it_is_called
|
302
|
+
@cache.write('foo', 'bar')
|
303
|
+
assert_not_equal @cache.read('foo').object_id, @cache.read('foo').object_id
|
304
|
+
value = @cache.read('foo')
|
305
|
+
value << 'bingo'
|
306
|
+
assert_not_equal value, @cache.read('foo')
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_original_store_objects_should_not_be_immutable
|
310
|
+
bar = 'bar'
|
311
|
+
@cache.write('foo', bar)
|
312
|
+
assert_nothing_raised { bar.gsub!(/.*/, 'baz') }
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_expires_in
|
316
|
+
time = Time.local(2008, 4, 24)
|
317
|
+
Time.stubs(:now).returns(time)
|
318
|
+
|
319
|
+
@cache.write('foo', 'bar')
|
320
|
+
assert_equal 'bar', @cache.read('foo')
|
321
|
+
|
322
|
+
Time.stubs(:now).returns(time + 30)
|
323
|
+
assert_equal 'bar', @cache.read('foo')
|
324
|
+
|
325
|
+
Time.stubs(:now).returns(time + 61)
|
326
|
+
assert_nil @cache.read('foo')
|
327
|
+
end
|
328
|
+
|
329
|
+
def test_race_condition_protection
|
330
|
+
time = Time.now
|
331
|
+
@cache.write('foo', 'bar', :expires_in => 60)
|
332
|
+
Time.stubs(:now).returns(time + 61)
|
333
|
+
result = @cache.fetch('foo', :race_condition_ttl => 10) do
|
334
|
+
assert_equal 'bar', @cache.read('foo')
|
335
|
+
"baz"
|
336
|
+
end
|
337
|
+
assert_equal "baz", result
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_race_condition_protection_is_limited
|
341
|
+
time = Time.now
|
342
|
+
@cache.write('foo', 'bar', :expires_in => 60)
|
343
|
+
Time.stubs(:now).returns(time + 71)
|
344
|
+
result = @cache.fetch('foo', :race_condition_ttl => 10) do
|
345
|
+
assert_equal nil, @cache.read('foo')
|
346
|
+
"baz"
|
347
|
+
end
|
348
|
+
assert_equal "baz", result
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_race_condition_protection_is_safe
|
352
|
+
time = Time.now
|
353
|
+
@cache.write('foo', 'bar', :expires_in => 60)
|
354
|
+
Time.stubs(:now).returns(time + 61)
|
355
|
+
begin
|
356
|
+
@cache.fetch('foo', :race_condition_ttl => 10) do
|
357
|
+
assert_equal 'bar', @cache.read('foo')
|
358
|
+
raise ArgumentError.new
|
359
|
+
end
|
360
|
+
rescue ArgumentError
|
361
|
+
end
|
362
|
+
assert_equal "bar", @cache.read('foo')
|
363
|
+
Time.stubs(:now).returns(time + 71)
|
364
|
+
assert_nil @cache.read('foo')
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_crazy_key_characters
|
368
|
+
crazy_key = "#/:*(<+=> )&$%@?;'\"\'`~-"
|
369
|
+
assert @cache.write(crazy_key, 1, :raw => true)
|
370
|
+
assert_equal 1, @cache.read(crazy_key)
|
371
|
+
assert_equal 1, @cache.fetch(crazy_key)
|
372
|
+
assert @cache.delete(crazy_key)
|
373
|
+
assert_equal 2, @cache.fetch(crazy_key, :raw => true) { 2 }
|
374
|
+
assert_equal 3, @cache.increment(crazy_key)
|
375
|
+
assert_equal 2, @cache.decrement(crazy_key)
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_really_long_keys
|
379
|
+
key = ""
|
380
|
+
900.times{key << "x"}
|
381
|
+
assert @cache.write(key, "bar")
|
382
|
+
assert_equal "bar", @cache.read(key)
|
383
|
+
assert_equal "bar", @cache.fetch(key)
|
384
|
+
assert_nil @cache.read("#{key}x")
|
385
|
+
assert_equal({key => "bar"}, @cache.read_multi(key))
|
386
|
+
assert @cache.delete(key)
|
387
|
+
end
|
388
|
+
end
|
data/test/ttl_test.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'abstract_unit'
|
2
|
+
require 'mongo'
|
3
|
+
require 'active_support/test_case'
|
4
|
+
require 'active_support/cache'
|
5
|
+
require_relative 'test_modules'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
class MongoCacheStoreTTLTest < ActiveSupport::TestCase
|
10
|
+
def setup
|
11
|
+
@cache = ActiveSupport::Cache.lookup_store(
|
12
|
+
:mongo_cache_store, :TTL,
|
13
|
+
:db => Mongo::DB.new('db_name',Mongo::Connection.new),
|
14
|
+
:expires_in => 60
|
15
|
+
)
|
16
|
+
@cache.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
include CacheStoreBehavior
|
20
|
+
# include LocalCacheBehavior
|
21
|
+
include CacheIncrementDecrementBehavior
|
22
|
+
# include EncodedKeyCacheBehavior
|
23
|
+
|
24
|
+
end
|
metadata
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo_cache_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Kevin McGrath
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-03-25 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: mongo
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: activesupport
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,19 +41,31 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rspec
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mocha
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.13.3
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.13.3
|
62
69
|
description: A MongoDB ActiveSupport Cache
|
63
70
|
email:
|
64
71
|
- kmcgrath@baknet.com
|
@@ -79,32 +86,37 @@ files:
|
|
79
86
|
- lib/active_support/cache/mongo_cache_store/backend/ttl.rb
|
80
87
|
- lib/mongo_cache_store/version.rb
|
81
88
|
- mongo_cache_store.gemspec
|
82
|
-
-
|
83
|
-
-
|
89
|
+
- test/abstract_unit.rb
|
90
|
+
- test/multi_ttl_test.rb
|
91
|
+
- test/standard_test.rb
|
92
|
+
- test/test_modules.rb
|
93
|
+
- test/ttl_test.rb
|
84
94
|
homepage: https://github.com/kmcgrath/mongo_cache_store
|
85
95
|
licenses: []
|
96
|
+
metadata: {}
|
86
97
|
post_install_message:
|
87
98
|
rdoc_options: []
|
88
99
|
require_paths:
|
89
100
|
- lib
|
90
101
|
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
-
none: false
|
92
102
|
requirements:
|
93
|
-
- -
|
103
|
+
- - '>='
|
94
104
|
- !ruby/object:Gem::Version
|
95
105
|
version: '0'
|
96
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
107
|
requirements:
|
99
|
-
- -
|
108
|
+
- - '>='
|
100
109
|
- !ruby/object:Gem::Version
|
101
110
|
version: '0'
|
102
111
|
requirements: []
|
103
112
|
rubyforge_project:
|
104
|
-
rubygems_version:
|
113
|
+
rubygems_version: 2.0.0.rc.2
|
105
114
|
signing_key:
|
106
|
-
specification_version:
|
115
|
+
specification_version: 4
|
107
116
|
summary: A MongoDB ActiveSupport Cache
|
108
117
|
test_files:
|
109
|
-
-
|
110
|
-
-
|
118
|
+
- test/abstract_unit.rb
|
119
|
+
- test/multi_ttl_test.rb
|
120
|
+
- test/standard_test.rb
|
121
|
+
- test/test_modules.rb
|
122
|
+
- test/ttl_test.rb
|
@@ -1,179 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
3
|
-
|
4
|
-
|
5
|
-
class MongoCacheStoreTestSaveClass
|
6
|
-
|
7
|
-
attr_reader :set_me
|
8
|
-
def initialize(set_me)
|
9
|
-
@set_me = set_me
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
module ActiveSupport
|
16
|
-
module Cache
|
17
|
-
class MongoCacheStoreTest
|
18
|
-
shared_examples "a cache store" do
|
19
|
-
describe "Caching" do
|
20
|
-
|
21
|
-
it "can write values" do
|
22
|
-
@store.write('forever!', 'I live forever!')
|
23
|
-
@store.fetch('forever!').should == "I live forever!"
|
24
|
-
end
|
25
|
-
|
26
|
-
it "can expire" do
|
27
|
-
@store.fetch 'testkey', expires_in: 2.minutes do
|
28
|
-
"I will expire."
|
29
|
-
end
|
30
|
-
@store.exist?("testkey").should == true
|
31
|
-
|
32
|
-
sleep 60
|
33
|
-
|
34
|
-
response = @store.fetch 'testkey'
|
35
|
-
response.should == "I will expire."
|
36
|
-
|
37
|
-
sleep 120
|
38
|
-
|
39
|
-
response = @store.fetch 'testkey'
|
40
|
-
response.should == nil
|
41
|
-
end
|
42
|
-
|
43
|
-
it "can cache a hash" do
|
44
|
-
@store.write('hashme',
|
45
|
-
{"1"=>{:name=>"Uptime", :zenoss_instance=>"cust", :path=>"/zport/RenderServer/render?gopts=k4VJvRM2K1Dahl3RzJWcqoicTSIz0QJ1Ja10idqC412ptG5_lrmcroRy3BDIqioB561tB4UjtjSg1ib_YaGOXBWOEHBhPbEmA6ZXXjd8LiIOmItqTDZjuFkZvOV38_CF_YEi7t9xUtFKOIxibyVo67jzbyK6P-ORc7i07rK5GUYeA2CnJxm4UDCNKcKRpDCzmdzR-NwcOp0w55KH8YeU6NpgHyM_tpu8G42d7nBQebs1DKvn20sktezqy_LiIizKk3eMzDW-c8w1EZTESWa4rIihXfHrrv9PNxvCw41wU9f3dxQt2c3OFfhSx6riSUbeVsUNEo6s_35KdKJkbr6rEZaaxL2RGR47eLBzifIcZAg="}, "2"=>{:name=>"CPU Utilization", :zenoss_instance=>"cust", :path=>"/zport/RenderServer/render?gopts=WN-Oc9wB_CFbVKzzN75ij-qQcZ6lSOC3jj_ALTzkdMEZ_EzgcvfWOdU7vmlrm9MFY6zrOUeW2Z_uzyJkhRrl_81bVs96xoa7y2S29NVU_oSIIxQj1rUElV04u3wGRXnEbfyYPjLp0m6QEDOthqCs3SLcc7jKkCI15V0Js1b6FpFleWdmO9dCMLvKqdBiE-yhSjfwPS7Rh0wPLAoxXTyIkFFHHBXIu_g69_xnESZhYz0rAWn0W0Ag5N46LuNqwbzW1PwIfczY1Hqw2iKQAq1C4fMry3DNiQvnRmUZdF_w11quhIo-XccH1em3iopVdyy6ik83vMvJN3DfhLUbXcZjnA=="}, "3"=>{:name=>"Memory Utilization", :instance=>"cust", :path=>"/zport/RenderServer/render?gopts=_E6b8KAZjy9xzEYtckX_RDQOsGfIRZnG5WRu7ekbUIlsgWmNZNJ8AgEfr7AM0rV6lZMC4PzCPacRN1zeVQ-nHgTBBDbq4sIQuUMl3ETW9DRM2wgjrmnCRwcl7Dz_qGL6PWkhsJzhQ231SuNi7pM6mDw8dbE_pmZ3F6xKa7_8frJLWoMGLji8sIklFf45YckRkIohkMsffZKMsIspx8JEOvR9mP24vGs0Wv4gRXxqFoE1FlgchuKf2KDvWbwp92RrdOmhOAqMxHWmNA2faAC75072ao9bf6UnxZUu5WFUcNsvJJFcEl2U30TEX5vyjf_9C-1Rvnyf8Q6ajvRKA1VNIl6fpItv8dsKTNViX27RWsI="}, "4"=>{:name=>"Swap", :instance=>"cust", :path=>"/zport/RenderServer/render?gopts=nBpbINZ6hhzV8IUJq49zWOTsQ4hX5F5ZGPyoHZ6KWPUx_4Xk0_URWbZPQO4yicu14u81lDFqfRCoFTwofkA0NJIqoOQfAx2gWrwbE7RtulqYeMol47KWQpSITLSV4Mkh1Sbp9VZqpc4YVjiu1EvWSOIHCeUPXZPSBWFh0R2VoPB_VutBricdimwkvRsHbU9-BlKyJcT-_vEnTMi2MHlB3iKWY329OkN-J2chI3MtoLvSw9sN2LJbrO4ynFQPX4WFY9D18Zhv1bzOapn0XcCsxj88XHZ2eZeEZ0uv33_9EKSVxKtOOYo3Y08mjEKduOme"}, "5"=>{:name=>"Load Average", :instance=>"cust", :path=>"/zport/RenderServer/render?gopts=0y-dExjiyMFT0yWeOf-FR3hBIgIVZZortlKSFUETQYjwMuSDfhB-JhsEYI-feAC0Bmh5T8fZQRuYi5MkD3C2S6Qwd_kzvPrjwxCfxjTaQzidN-DxlWjqTkTfZ-AiPQ3F8JVXr-8kP8ZA10XDcV2VpIHJwZatzxDBVk7isEdKAXEJm-1X_TY7BCdU9uFlcBT1XGEYESM5anyR3282Z77yiYX6PsUcoPwFtLzg1l6Ql8cda8n4d2zLK4ZBX5G25ZQoC0MAmHZPyXRIsI-GGZjKcvXHjZ350tEpyvPiSX8a7PG-dRtWIGEEecM9czU3MF5Xzl-qOVfoRWc8pmlc-5E37Z5TcAoZpUHSlssJdjwoLfOlhFkLGyAVZpVXRCVRWdXNxilLS9N4GbuIEqhsEILyM0MzPvEHwPO3rcPSlzcS4s_SXnjp6XLg2bB6NZjAvbz5Vyb6OPg-8b9C-MmzcpWzVHzP5nYo9RVPR_lpFcmOBUSO_cJO22pIqqMyn1vXbtVz"}, "6"=>{:name=>"Paging", :instance=>"cust", :path=>"/zport/RenderServer/render?gopts=N7sjMwpMD3JE0ZNya07IgWj6t7yn7uX4GJ1XHlmyhRcqcea0HpfXTen6ptASVAZIvWT7fW4kufkvtNBsxKfDMX9JMzqoR-kpfWqoRRfI3eGmqYecg6gcQgXSEnu5Mzf4r-lbo1_Cqp8dYuSmC37uWrKi0gTWVr54ZmQ6w4dSymQ4xSkCH2-MO1X8wxZdtm804NJy6yQ4l7JZYBkWD9rABoPhVfZq4mZpHmZN27UlbK14Z9R3EEF6MG0jKCbJ7gJVEjpOoX_y5ka4S3aRULFSByrZIA290_ZMO21DAnsJbJyMXAEP9r8UanaotdVrPLSOXJkYD4WvdcdDeZ3wMtvdL42oHdhwLDyG9J8i9GkcvwsU04MlTTl270LkX31HJjxjB8IChpDke-9LEmxG_1icmGcAcWr26gTk9HOULwTyso4sX_ZqqCnrrnRRQLCpCZtlqxIB9iAMUtSdkEUdZlsAuw=="}},
|
46
|
-
expires_in: 1.hour
|
47
|
-
)
|
48
|
-
|
49
|
-
hash = @store.read('hashme')
|
50
|
-
hash["1"].should be_a_kind_of(Hash)
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
it "can cache class instances" do
|
55
|
-
@store.fetch 'my_class', expires_in: 30.seconds do
|
56
|
-
MongoCacheStoreTestSaveClass.new('what did i say?')
|
57
|
-
end
|
58
|
-
|
59
|
-
my_class = @store.fetch 'my_class'
|
60
|
-
my_class.set_me.should == 'what did i say?'
|
61
|
-
end
|
62
|
-
|
63
|
-
it "can use a hash as a key" do
|
64
|
-
hash_key = {
|
65
|
-
:class_name => 'my_class',
|
66
|
-
:option2 => 2
|
67
|
-
}
|
68
|
-
|
69
|
-
miss_key = {
|
70
|
-
:class_name => 'my_class',
|
71
|
-
:option2 => 1
|
72
|
-
}
|
73
|
-
|
74
|
-
hit_key = {
|
75
|
-
:class_name => 'my_class',
|
76
|
-
:option2 => 2
|
77
|
-
}
|
78
|
-
|
79
|
-
|
80
|
-
@store.fetch(hash_key, expires_in: 30.seconds) do
|
81
|
-
MongoCacheStoreTestSaveClass.new('what did i say?')
|
82
|
-
end
|
83
|
-
|
84
|
-
my_class = @store.fetch(hash_key)
|
85
|
-
my_class.set_me.should == 'what did i say?'
|
86
|
-
|
87
|
-
my_class = @store.fetch(hit_key)
|
88
|
-
my_class.set_me.should == 'what did i say?'
|
89
|
-
|
90
|
-
my_class = @store.fetch(miss_key)
|
91
|
-
my_class.should == nil
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
after(:all) do
|
96
|
-
@store.clear.should == true
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
describe MongoCacheStore do
|
103
|
-
describe "initializing" do
|
104
|
-
it "can take a Mongo::DB object" do
|
105
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
106
|
-
store = ActiveSupport::Cache::MongoCacheStore.new(:TTL, :db => db)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe "TTL Caching" do
|
111
|
-
it_behaves_like "a cache store"
|
112
|
-
before(:all) do
|
113
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
114
|
-
@store = ActiveSupport::Cache::MongoCacheStore.new(:TTL, :db => db)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
describe "TTL Caching On Fail Serialization" do
|
119
|
-
it_behaves_like "a cache store"
|
120
|
-
before(:all) do
|
121
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
122
|
-
@store = ActiveSupport::Cache::MongoCacheStore.new(:TTL, :db => db, :serialize => :on_fail)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe "MultiTTL Caching" do
|
127
|
-
it_behaves_like "a cache store"
|
128
|
-
before(:all) do
|
129
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
130
|
-
@store = ActiveSupport::Cache::MongoCacheStore.new(:MultiTTL, :db => db)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
describe "MultiTTL Caching On Fail Serialization" do
|
135
|
-
it_behaves_like "a cache store"
|
136
|
-
before(:all) do
|
137
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
138
|
-
@store = ActiveSupport::Cache::MongoCacheStore.new(:MultiTTL, :db => db, :serialize => :on_fail)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe "Standard Caching" do
|
143
|
-
it_behaves_like "a cache store"
|
144
|
-
before(:all) do
|
145
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
146
|
-
@store = ActiveSupport::Cache::MongoCacheStore.new(:Standard, :db => db)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
describe "Standard Caching On Fail Serialization" do
|
151
|
-
it_behaves_like "a cache store"
|
152
|
-
before(:all) do
|
153
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
154
|
-
@store = ActiveSupport::Cache::MongoCacheStore.new(:Standard, :db => db, :serialize => :on_fail)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
describe "Pass Collection Options" do
|
159
|
-
before(:all) do
|
160
|
-
db = Mongo::DB.new('mongo_cache_store_test', Mongo::Connection.new)
|
161
|
-
@store = ActiveSupport::Cache::MongoCacheStore.new(
|
162
|
-
:Standard,
|
163
|
-
:db => db,
|
164
|
-
:collection_opts => {
|
165
|
-
:read => :nearest
|
166
|
-
}
|
167
|
-
)
|
168
|
-
end
|
169
|
-
|
170
|
-
it "can set collection opts" do
|
171
|
-
col = @store.send(:get_collection,{:collection_opts => {:read => :nearest}})
|
172
|
-
col.instance_eval { @read }.should == :nearest
|
173
|
-
end
|
174
|
-
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|