redis-store 1.10.0 → 1.12.0
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 +4 -4
- data/lib/redis/store/factory.rb +8 -1
- data/lib/redis/store/version.rb +1 -1
- data/lib/redis/store.rb +2 -0
- metadata +23 -36
- data/.codeclimate.yml +0 -6
- data/.github/auto-assign-issues.yml +0 -2
- data/.github/release.yml +0 -13
- data/.github/workflows/ci.yml +0 -64
- data/.github/workflows/publish.yml +0 -32
- data/.gitignore +0 -9
- data/.rubocop.yml +0 -132
- data/Appraisals +0 -19
- data/CODEOWNERS +0 -1
- data/Gemfile +0 -7
- data/Rakefile +0 -15
- data/gemfiles/redis_4_0_x.gemfile +0 -7
- data/gemfiles/redis_4_1_x.gemfile +0 -7
- data/gemfiles/redis_4_6_x.gemfile +0 -7
- data/gemfiles/redis_4_x.gemfile +0 -7
- data/gemfiles/redis_5_x.gemfile +0 -7
- data/redis-store.gemspec +0 -31
- data/test/redis/distributed_store_test.rb +0 -111
- data/test/redis/store/factory_test.rb +0 -273
- data/test/redis/store/interface_test.rb +0 -27
- data/test/redis/store/namespace_test.rb +0 -317
- data/test/redis/store/redis_version_test.rb +0 -28
- data/test/redis/store/serialization_test.rb +0 -173
- data/test/redis/store/ttl_test.rb +0 -142
- data/test/redis/store/version_test.rb +0 -7
- data/test/redis/store_test.rb +0 -68
- data/test/test_helper.rb +0 -20
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
describe "Redis::Serialization" do
|
|
4
|
-
def setup
|
|
5
|
-
@store = Redis::Store.new serializer: Marshal
|
|
6
|
-
@rabbit = OpenStruct.new :name => "bunny"
|
|
7
|
-
@white_rabbit = OpenStruct.new :color => "white"
|
|
8
|
-
@store.set "rabbit", @rabbit
|
|
9
|
-
@store.del "rabbit2"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def teardown
|
|
13
|
-
@store.flushdb
|
|
14
|
-
@store.quit
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "unmarshals on get" do
|
|
18
|
-
_(@store.get("rabbit")).must_equal(@rabbit)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "marshals on set" do
|
|
22
|
-
@store.set "rabbit", @white_rabbit
|
|
23
|
-
_(@store.get("rabbit")).must_equal(@white_rabbit)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "marshals on multi set" do
|
|
27
|
-
@store.mset("rabbit", @white_rabbit, "rabbit2", @rabbit)
|
|
28
|
-
_(@store.get("rabbit")).must_equal(@white_rabbit)
|
|
29
|
-
_(@store.get("rabbit2")).must_equal(@rabbit)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
if RUBY_VERSION.match(/1\.9/)
|
|
33
|
-
it "doesn't unmarshal on get if raw option is true" do
|
|
34
|
-
_(@store.get("rabbit", :raw => true)).must_equal("\x04\bU:\x0FOpenStruct{\x06:\tnameI\"\nbunny\x06:\x06EF")
|
|
35
|
-
end
|
|
36
|
-
else
|
|
37
|
-
it "doesn't unmarshal on get if raw option is true" do
|
|
38
|
-
_(@store.get("rabbit", :raw => true)).must_include("\x04\bU:\x0FOpenStruct{\x06:\tname")
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "doesn't marshal set if raw option is true" do
|
|
43
|
-
@store.set "rabbit", @white_rabbit, :raw => true
|
|
44
|
-
_(@store.get("rabbit", :raw => true)).must_equal(%(#<OpenStruct color="white">))
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it "doesn't marshal multi set if raw option is true" do
|
|
48
|
-
@store.mset("rabbit", @white_rabbit, "rabbit2", @rabbit, :raw => true)
|
|
49
|
-
_(@store.get("rabbit", :raw => true)).must_equal(%(#<OpenStruct color="white">))
|
|
50
|
-
_(@store.get("rabbit2", :raw => true)).must_equal(%(#<OpenStruct name="bunny">))
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "doesn't unmarshal if get returns an empty string" do
|
|
54
|
-
@store.set "empty_string", ""
|
|
55
|
-
_(@store.get("empty_string")).must_equal("")
|
|
56
|
-
# TODO use a meaningful Exception
|
|
57
|
-
# lambda { @store.get("empty_string").must_equal("") }.wont_raise Exception
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it "doesn't set an object if already exist" do
|
|
61
|
-
@store.setnx "rabbit", @white_rabbit
|
|
62
|
-
_(@store.get("rabbit")).must_equal(@rabbit)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it "marshals on set unless exists" do
|
|
66
|
-
@store.setnx "rabbit2", @white_rabbit
|
|
67
|
-
_(@store.get("rabbit2")).must_equal(@white_rabbit)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it "doesn't marshal on set unless exists if raw option is true" do
|
|
71
|
-
@store.setnx "rabbit2", @white_rabbit, :raw => true
|
|
72
|
-
_(@store.get("rabbit2", :raw => true)).must_equal(%(#<OpenStruct color="white">))
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "marshals on set expire" do
|
|
76
|
-
@store.setex "rabbit2", 1, @white_rabbit
|
|
77
|
-
_(@store.get("rabbit2")).must_equal(@white_rabbit)
|
|
78
|
-
sleep 2
|
|
79
|
-
_(@store.get("rabbit2")).must_be_nil
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
unless ENV['CI']
|
|
83
|
-
it "marshals setex (over a distributed store)" do
|
|
84
|
-
@store = Redis::DistributedStore.new [
|
|
85
|
-
{ :host => "localhost", :port => "6380", :db => 0 },
|
|
86
|
-
{ :host => "localhost", :port => "6381", :db => 0 }
|
|
87
|
-
]
|
|
88
|
-
@store.setex "rabbit", 50, @white_rabbit
|
|
89
|
-
_(@store.get("rabbit")).must_equal(@white_rabbit)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
it "doesn't marshal setex if raw option is true (over a distributed store)" do
|
|
93
|
-
@store = Redis::DistributedStore.new [
|
|
94
|
-
{ :host => "localhost", :port => "6380", :db => 0 },
|
|
95
|
-
{ :host => "localhost", :port => "6381", :db => 0 }
|
|
96
|
-
]
|
|
97
|
-
@store.setex "rabbit", 50, @white_rabbit, :raw => true
|
|
98
|
-
_(@store.get("rabbit", :raw => true)).must_equal(%(#<OpenStruct color="white">))
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
it "unmarshals on multi get" do
|
|
103
|
-
@store.set "rabbit2", @white_rabbit
|
|
104
|
-
@store.mget "rabbit", "rabbit2" do |rabbits|
|
|
105
|
-
rabbit, rabbit2 = rabbits
|
|
106
|
-
_(rabbits.length).must_equal(2)
|
|
107
|
-
_(rabbit).must_equal(@rabbit)
|
|
108
|
-
_(rabbit2).must_equal(@white_rabbit)
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
it "unmarshals on mapped_mget" do
|
|
113
|
-
@store.set "rabbit2", @white_rabbit
|
|
114
|
-
result = @store.mapped_mget("rabbit", "rabbit2")
|
|
115
|
-
_(result.keys).must_equal %w[ rabbit rabbit2 ]
|
|
116
|
-
_(result["rabbit"]).must_equal @rabbit
|
|
117
|
-
_(result["rabbit2"]).must_equal @white_rabbit
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
if RUBY_VERSION.match(/1\.9/)
|
|
121
|
-
it "doesn't unmarshal on multi get if raw option is true" do
|
|
122
|
-
@store.set "rabbit2", @white_rabbit
|
|
123
|
-
@store.mget "rabbit", "rabbit2", :raw => true do |rabbit, rabbit2|
|
|
124
|
-
_(rabbit).must_equal("\x04\bU:\x0FOpenStruct{\x06:\tnameI\"\nbunny\x06:\x06EF")
|
|
125
|
-
_(rabbit2).must_equal("\x04\bU:\x0FOpenStruct{\x06:\ncolorI\"\nwhite\x06:\x06EF")
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
else
|
|
129
|
-
it "doesn't unmarshal on multi get if raw option is true" do
|
|
130
|
-
@store.set "rabbit2", @white_rabbit
|
|
131
|
-
@store.mget "rabbit", "rabbit2", :raw => true do |rabbit, rabbit2|
|
|
132
|
-
_(rabbit).must_include("\x04\bU:\x0FOpenStruct{\x06:\tname")
|
|
133
|
-
_(rabbit2).must_include("\x04\bU:\x0FOpenStruct{\x06:\ncolor")
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
describe "binary safety" do
|
|
139
|
-
it "marshals objects" do
|
|
140
|
-
utf8_key = [51339].pack("U*")
|
|
141
|
-
ascii_rabbit = OpenStruct.new(:name => [128].pack("C*"))
|
|
142
|
-
|
|
143
|
-
@store.set(utf8_key, ascii_rabbit)
|
|
144
|
-
_(@store.get(utf8_key)).must_equal(ascii_rabbit)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
it "gets and sets raw values" do
|
|
148
|
-
utf8_key = [51339].pack("U*")
|
|
149
|
-
ascii_string = [128].pack("C*")
|
|
150
|
-
|
|
151
|
-
@store.set(utf8_key, ascii_string, :raw => true)
|
|
152
|
-
_(@store.get(utf8_key, :raw => true).bytes.to_a).must_equal(ascii_string.bytes.to_a)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
it "marshals objects on setnx" do
|
|
156
|
-
utf8_key = [51339].pack("U*")
|
|
157
|
-
ascii_rabbit = OpenStruct.new(:name => [128].pack("C*"))
|
|
158
|
-
|
|
159
|
-
@store.del(utf8_key)
|
|
160
|
-
@store.setnx(utf8_key, ascii_rabbit)
|
|
161
|
-
_(@store.get(utf8_key)).must_equal(ascii_rabbit)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
it "gets and sets raw values on setnx" do
|
|
165
|
-
utf8_key = [51339].pack("U*")
|
|
166
|
-
ascii_string = [128].pack("C*")
|
|
167
|
-
|
|
168
|
-
@store.del(utf8_key)
|
|
169
|
-
@store.setnx(utf8_key, ascii_string, :raw => true)
|
|
170
|
-
_(@store.get(utf8_key, :raw => true).bytes.to_a).must_equal(ascii_string.bytes.to_a)
|
|
171
|
-
end
|
|
172
|
-
end if defined?(Encoding)
|
|
173
|
-
end
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
class MockRedis
|
|
4
|
-
def initialize
|
|
5
|
-
@sets = []
|
|
6
|
-
@setexes = []
|
|
7
|
-
@setnxes = []
|
|
8
|
-
@expires = []
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def set(*a)
|
|
12
|
-
@sets << a
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def has_set?(*a)
|
|
16
|
-
@sets.include?(a)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def setex(*a)
|
|
20
|
-
@setexes << a
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def has_setex?(*a)
|
|
24
|
-
@setexes.include?(a)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def setnx(*a)
|
|
28
|
-
@setnxes << a
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def has_setnx?(*a)
|
|
32
|
-
@setnxes.include?(a)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def multi(&block)
|
|
36
|
-
instance_eval do
|
|
37
|
-
def setnx(*a)
|
|
38
|
-
@setnxes << a
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
block.call(self)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
alias_method :pipelined, :multi
|
|
45
|
-
|
|
46
|
-
def expire(*a)
|
|
47
|
-
@expires << a
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def has_expire?(*a)
|
|
51
|
-
@expires.include?(a)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
class MockTtlStore < MockRedis
|
|
56
|
-
include Redis::Store::Ttl
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
describe MockTtlStore do
|
|
60
|
-
let(:key) { 'hello' }
|
|
61
|
-
let(:mock_value) { 'value' }
|
|
62
|
-
let(:options) { { :expire_after => 3600 } }
|
|
63
|
-
let(:redis) { MockTtlStore.new }
|
|
64
|
-
|
|
65
|
-
describe '#set' do
|
|
66
|
-
describe 'without options' do
|
|
67
|
-
it 'must call super with key and value' do
|
|
68
|
-
redis.set(key, mock_value)
|
|
69
|
-
_(redis.has_set?(key, mock_value, nil)).must_equal true
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
describe 'with options' do
|
|
74
|
-
it 'must call setex with proper expiry and set raw to true' do
|
|
75
|
-
redis.set(key, mock_value, options)
|
|
76
|
-
_(redis.has_setex?(key, options[:expire_after], mock_value, :raw => true)).must_equal true
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
describe 'with nx and ex option' do
|
|
81
|
-
it 'must call super with key and value and options' do
|
|
82
|
-
set_options = { nx: true, ex: 3600 }
|
|
83
|
-
redis.set(key, mock_value, set_options)
|
|
84
|
-
_(redis.has_set?(key, mock_value, set_options)).must_equal true
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
describe '#setnx' do
|
|
90
|
-
describe 'without expiry' do
|
|
91
|
-
it 'must call super with key and value' do
|
|
92
|
-
redis.setnx(key, mock_value)
|
|
93
|
-
redis.has_setnx?(key, mock_value)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
it 'must not call expire' do
|
|
97
|
-
redis.expects(:expire).never
|
|
98
|
-
redis.setnx(key, mock_value)
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
describe 'with expiry' do
|
|
103
|
-
it 'uses the mutli command to chain commands' do
|
|
104
|
-
redis.expects(:multi)
|
|
105
|
-
redis.setnx(key, mock_value, options)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
it 'must call expire' do
|
|
109
|
-
redis.setnx(key, mock_value, options)
|
|
110
|
-
_(redis.has_expire?(key, options[:expire_after])).must_equal true
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
describe 'avoiding multi commands' do
|
|
114
|
-
let(:options) { { :expire_after => 3600, :avoid_multi_commands => true } }
|
|
115
|
-
|
|
116
|
-
it 'uses the redis pipelined feature to chain commands' do
|
|
117
|
-
redis.expects(:pipelined)
|
|
118
|
-
redis.setnx(key, mock_value, options)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
it 'must call expire' do
|
|
122
|
-
redis.setnx(key, mock_value, options)
|
|
123
|
-
_(redis.has_expire?(key, options[:expire_after])).must_equal true
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
describe 'using a redis cluster' do
|
|
128
|
-
let(:options) { { :expire_after => 3600, :cluster => %w[redis://127.0.0.1:6379/0] } }
|
|
129
|
-
|
|
130
|
-
it 'uses the redis pipelined feature to chain commands' do
|
|
131
|
-
redis.expects(:pipelined)
|
|
132
|
-
redis.setnx(key, mock_value, options)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
it 'must call expire' do
|
|
136
|
-
redis.setnx(key, mock_value, options)
|
|
137
|
-
_(redis.has_expire?(key, options[:expire_after])).must_equal true
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
data/test/redis/store_test.rb
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
describe Redis::Store do
|
|
4
|
-
def setup
|
|
5
|
-
@store = Redis::Store.new
|
|
6
|
-
@client = @store.instance_variable_get(:@client)
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def teardown
|
|
10
|
-
@store.flushdb
|
|
11
|
-
@store.quit
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "returns useful informations about the server" do
|
|
15
|
-
_(@store.to_s).must_equal("Redis Client connected to #{@client.host}:#{@client.port} against DB #{@client.db}")
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "must force reconnection" do
|
|
19
|
-
@client.expects(:reconnect)
|
|
20
|
-
@store.reconnect
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe '#set' do
|
|
24
|
-
describe 'with expiry' do
|
|
25
|
-
let(:options) { { :expire_after => 3600 } }
|
|
26
|
-
|
|
27
|
-
it 'must not double marshall' do
|
|
28
|
-
Marshal.expects(:dump).once
|
|
29
|
-
|
|
30
|
-
@store.set('key', 'value', options)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
describe 'with ex and nx' do
|
|
35
|
-
let(:key) { 'key' }
|
|
36
|
-
let(:mock_value) { 'value' }
|
|
37
|
-
let(:options) { { nx: true, ex: 3600 } }
|
|
38
|
-
|
|
39
|
-
it 'must pass on options' do
|
|
40
|
-
Marshal.expects(:dump).times(4)
|
|
41
|
-
|
|
42
|
-
# without options no ex or nx will be set
|
|
43
|
-
@store.del(key)
|
|
44
|
-
_(@store.set(key, mock_value, {})).must_equal 'OK'
|
|
45
|
-
_(@store.set(key, mock_value, {})).must_equal 'OK'
|
|
46
|
-
_(@store.ttl(key)).must_equal(-1)
|
|
47
|
-
|
|
48
|
-
# with ex and nx options, the key can only be set once and a ttl will be set
|
|
49
|
-
@store.del(key)
|
|
50
|
-
_(@store.set(key, mock_value, options)).must_equal true
|
|
51
|
-
_(@store.set(key, mock_value, options)).must_equal false
|
|
52
|
-
_(@store.ttl(key)).must_equal 3600
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
describe '#setnx' do
|
|
58
|
-
describe 'with expiry' do
|
|
59
|
-
let(:options) { { :expire_after => 3600 } }
|
|
60
|
-
|
|
61
|
-
it 'must not double marshall' do
|
|
62
|
-
Marshal.expects(:dump).once
|
|
63
|
-
|
|
64
|
-
@store.setnx('key', 'value', options)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
data/test/test_helper.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require 'bundler/setup'
|
|
2
|
-
require 'minitest/autorun'
|
|
3
|
-
require 'mocha/minitest'
|
|
4
|
-
require 'redis'
|
|
5
|
-
require 'redis-store'
|
|
6
|
-
|
|
7
|
-
$DEBUG = ENV["DEBUG"] === "true"
|
|
8
|
-
|
|
9
|
-
Redis::DistributedStore.send(:class_variable_set, :@@timeout, 30)
|
|
10
|
-
|
|
11
|
-
# http://mentalized.net/journal/2010/04/02/suppress_warnings_from_ruby/
|
|
12
|
-
module Kernel
|
|
13
|
-
def suppress_warnings
|
|
14
|
-
original_verbosity = $VERBOSE
|
|
15
|
-
$VERBOSE = nil
|
|
16
|
-
result = yield
|
|
17
|
-
$VERBOSE = original_verbosity
|
|
18
|
-
result
|
|
19
|
-
end
|
|
20
|
-
end
|