redis 3.3.3 → 5.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +280 -12
- data/README.md +141 -147
- data/lib/redis/client.rb +77 -539
- data/lib/redis/commands/bitmaps.rb +66 -0
- data/lib/redis/commands/cluster.rb +28 -0
- data/lib/redis/commands/connection.rb +53 -0
- data/lib/redis/commands/geo.rb +84 -0
- data/lib/redis/commands/hashes.rb +254 -0
- data/lib/redis/commands/hyper_log_log.rb +37 -0
- data/lib/redis/commands/keys.rb +437 -0
- data/lib/redis/commands/lists.rb +285 -0
- data/lib/redis/commands/pubsub.rb +54 -0
- data/lib/redis/commands/scripting.rb +114 -0
- data/lib/redis/commands/server.rb +188 -0
- data/lib/redis/commands/sets.rb +214 -0
- data/lib/redis/commands/sorted_sets.rb +818 -0
- data/lib/redis/commands/streams.rb +384 -0
- data/lib/redis/commands/strings.rb +314 -0
- data/lib/redis/commands/transactions.rb +115 -0
- data/lib/redis/commands.rb +235 -0
- data/lib/redis/distributed.rb +300 -108
- data/lib/redis/errors.rb +22 -1
- data/lib/redis/hash_ring.rb +36 -79
- data/lib/redis/pipeline.rb +69 -83
- data/lib/redis/subscribe.rb +26 -19
- data/lib/redis/version.rb +3 -1
- data/lib/redis.rb +113 -2685
- metadata +40 -218
- data/.gitignore +0 -16
- data/.travis/Gemfile +0 -11
- data/.travis.yml +0 -89
- data/.yardopts +0 -3
- data/Gemfile +0 -4
- data/Rakefile +0 -87
- data/benchmarking/logging.rb +0 -71
- data/benchmarking/pipeline.rb +0 -51
- data/benchmarking/speed.rb +0 -21
- data/benchmarking/suite.rb +0 -24
- data/benchmarking/worker.rb +0 -71
- data/examples/basic.rb +0 -15
- data/examples/consistency.rb +0 -114
- data/examples/dist_redis.rb +0 -43
- data/examples/incr-decr.rb +0 -17
- data/examples/list.rb +0 -26
- data/examples/pubsub.rb +0 -37
- data/examples/sentinel/sentinel.conf +0 -9
- data/examples/sentinel/start +0 -49
- data/examples/sentinel.rb +0 -41
- data/examples/sets.rb +0 -36
- data/examples/unicorn/config.ru +0 -3
- data/examples/unicorn/unicorn.rb +0 -20
- data/lib/redis/connection/command_helper.rb +0 -44
- data/lib/redis/connection/hiredis.rb +0 -66
- data/lib/redis/connection/registry.rb +0 -12
- data/lib/redis/connection/ruby.rb +0 -429
- data/lib/redis/connection/synchrony.rb +0 -133
- data/lib/redis/connection.rb +0 -9
- data/redis.gemspec +0 -44
- data/test/bitpos_test.rb +0 -69
- data/test/blocking_commands_test.rb +0 -42
- data/test/client_test.rb +0 -59
- data/test/command_map_test.rb +0 -30
- data/test/commands_on_hashes_test.rb +0 -21
- data/test/commands_on_hyper_log_log_test.rb +0 -21
- data/test/commands_on_lists_test.rb +0 -20
- data/test/commands_on_sets_test.rb +0 -77
- data/test/commands_on_sorted_sets_test.rb +0 -137
- data/test/commands_on_strings_test.rb +0 -101
- data/test/commands_on_value_types_test.rb +0 -133
- data/test/connection_handling_test.rb +0 -277
- data/test/db/.gitkeep +0 -0
- data/test/distributed_blocking_commands_test.rb +0 -46
- data/test/distributed_commands_on_hashes_test.rb +0 -10
- data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
- data/test/distributed_commands_on_lists_test.rb +0 -22
- data/test/distributed_commands_on_sets_test.rb +0 -83
- data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
- data/test/distributed_commands_on_strings_test.rb +0 -59
- data/test/distributed_commands_on_value_types_test.rb +0 -95
- data/test/distributed_commands_requiring_clustering_test.rb +0 -164
- data/test/distributed_connection_handling_test.rb +0 -23
- data/test/distributed_internals_test.rb +0 -79
- data/test/distributed_key_tags_test.rb +0 -52
- data/test/distributed_persistence_control_commands_test.rb +0 -26
- data/test/distributed_publish_subscribe_test.rb +0 -92
- data/test/distributed_remote_server_control_commands_test.rb +0 -66
- data/test/distributed_scripting_test.rb +0 -102
- data/test/distributed_sorting_test.rb +0 -20
- data/test/distributed_test.rb +0 -58
- data/test/distributed_transactions_test.rb +0 -32
- data/test/encoding_test.rb +0 -18
- data/test/error_replies_test.rb +0 -59
- data/test/fork_safety_test.rb +0 -65
- data/test/helper.rb +0 -232
- data/test/helper_test.rb +0 -24
- data/test/internals_test.rb +0 -457
- data/test/lint/blocking_commands.rb +0 -150
- data/test/lint/hashes.rb +0 -162
- data/test/lint/hyper_log_log.rb +0 -60
- data/test/lint/lists.rb +0 -143
- data/test/lint/sets.rb +0 -140
- data/test/lint/sorted_sets.rb +0 -316
- data/test/lint/strings.rb +0 -260
- data/test/lint/value_types.rb +0 -122
- data/test/persistence_control_commands_test.rb +0 -26
- data/test/pipelining_commands_test.rb +0 -242
- data/test/publish_subscribe_test.rb +0 -282
- data/test/remote_server_control_commands_test.rb +0 -118
- data/test/scanning_test.rb +0 -413
- data/test/scripting_test.rb +0 -78
- data/test/sentinel_command_test.rb +0 -80
- data/test/sentinel_test.rb +0 -255
- data/test/sorting_test.rb +0 -59
- data/test/ssl_test.rb +0 -73
- data/test/support/connection/hiredis.rb +0 -1
- data/test/support/connection/ruby.rb +0 -1
- data/test/support/connection/synchrony.rb +0 -17
- data/test/support/redis_mock.rb +0 -130
- data/test/support/ssl/gen_certs.sh +0 -31
- data/test/support/ssl/trusted-ca.crt +0 -25
- data/test/support/ssl/trusted-ca.key +0 -27
- data/test/support/ssl/trusted-cert.crt +0 -81
- data/test/support/ssl/trusted-cert.key +0 -28
- data/test/support/ssl/untrusted-ca.crt +0 -26
- data/test/support/ssl/untrusted-ca.key +0 -27
- data/test/support/ssl/untrusted-cert.crt +0 -82
- data/test/support/ssl/untrusted-cert.key +0 -28
- data/test/support/wire/synchrony.rb +0 -24
- data/test/support/wire/thread.rb +0 -5
- data/test/synchrony_driver.rb +0 -88
- data/test/test.conf.erb +0 -9
- data/test/thread_safety_test.rb +0 -62
- data/test/transactions_test.rb +0 -264
- data/test/unknown_commands_test.rb +0 -14
- data/test/url_param_test.rb +0 -138
data/test/sentinel_test.rb
DELETED
@@ -1,255 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
class SentinelTest < Test::Unit::TestCase
|
6
|
-
|
7
|
-
include Helper::Client
|
8
|
-
|
9
|
-
def test_sentinel_connection
|
10
|
-
sentinels = [{:host => "127.0.0.1", :port => 26381},
|
11
|
-
{:host => "127.0.0.1", :port => 26382}]
|
12
|
-
|
13
|
-
commands = {
|
14
|
-
:s1 => [],
|
15
|
-
:s2 => [],
|
16
|
-
}
|
17
|
-
|
18
|
-
handler = lambda do |id|
|
19
|
-
{
|
20
|
-
:sentinel => lambda do |command, *args|
|
21
|
-
commands[id] << [command, *args]
|
22
|
-
["127.0.0.1", "6381"]
|
23
|
-
end
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
RedisMock.start(handler.call(:s1)) do |s1_port|
|
28
|
-
RedisMock.start(handler.call(:s2)) do |s2_port|
|
29
|
-
sentinels[0][:port] = s1_port
|
30
|
-
sentinels[1][:port] = s2_port
|
31
|
-
redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master)
|
32
|
-
|
33
|
-
assert redis.ping
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
assert_equal commands[:s1], [%w[get-master-addr-by-name master1]]
|
38
|
-
assert_equal commands[:s2], []
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_sentinel_failover
|
42
|
-
sentinels = [{:host => "127.0.0.1", :port => 26381},
|
43
|
-
{:host => "127.0.0.1", :port => 26382}]
|
44
|
-
|
45
|
-
commands = {
|
46
|
-
:s1 => [],
|
47
|
-
:s2 => [],
|
48
|
-
}
|
49
|
-
|
50
|
-
s1 = {
|
51
|
-
:sentinel => lambda do |command, *args|
|
52
|
-
commands[:s1] << [command, *args]
|
53
|
-
"$-1" # Nil
|
54
|
-
end
|
55
|
-
}
|
56
|
-
|
57
|
-
s2 = {
|
58
|
-
:sentinel => lambda do |command, *args|
|
59
|
-
commands[:s2] << [command, *args]
|
60
|
-
["127.0.0.1", "6381"]
|
61
|
-
end
|
62
|
-
}
|
63
|
-
|
64
|
-
RedisMock.start(s1) do |s1_port|
|
65
|
-
RedisMock.start(s2) do |s2_port|
|
66
|
-
sentinels[0][:port] = s1_port
|
67
|
-
sentinels[1][:port] = s2_port
|
68
|
-
redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master)
|
69
|
-
|
70
|
-
assert redis.ping
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
assert_equal commands[:s1], [%w[get-master-addr-by-name master1]]
|
75
|
-
assert_equal commands[:s2], [%w[get-master-addr-by-name master1]]
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_sentinel_failover_prioritize_healthy_sentinel
|
79
|
-
sentinels = [{:host => "127.0.0.1", :port => 26381},
|
80
|
-
{:host => "127.0.0.1", :port => 26382}]
|
81
|
-
|
82
|
-
commands = {
|
83
|
-
:s1 => [],
|
84
|
-
:s2 => [],
|
85
|
-
}
|
86
|
-
|
87
|
-
s1 = {
|
88
|
-
:sentinel => lambda do |command, *args|
|
89
|
-
commands[:s1] << [command, *args]
|
90
|
-
"$-1" # Nil
|
91
|
-
end
|
92
|
-
}
|
93
|
-
|
94
|
-
s2 = {
|
95
|
-
:sentinel => lambda do |command, *args|
|
96
|
-
commands[:s2] << [command, *args]
|
97
|
-
["127.0.0.1", "6381"]
|
98
|
-
end
|
99
|
-
}
|
100
|
-
|
101
|
-
RedisMock.start(s1) do |s1_port|
|
102
|
-
RedisMock.start(s2) do |s2_port|
|
103
|
-
sentinels[0][:port] = s1_port
|
104
|
-
sentinels[1][:port] = s2_port
|
105
|
-
redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master)
|
106
|
-
|
107
|
-
assert redis.ping
|
108
|
-
|
109
|
-
redis.quit
|
110
|
-
|
111
|
-
assert redis.ping
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
assert_equal commands[:s1], [%w[get-master-addr-by-name master1]]
|
116
|
-
assert_equal commands[:s2], [%w[get-master-addr-by-name master1], %w[get-master-addr-by-name master1]]
|
117
|
-
end
|
118
|
-
|
119
|
-
def test_sentinel_with_non_sentinel_options
|
120
|
-
sentinels = [{:host => "127.0.0.1", :port => 26381}]
|
121
|
-
|
122
|
-
commands = {
|
123
|
-
:s1 => [],
|
124
|
-
:m1 => []
|
125
|
-
}
|
126
|
-
|
127
|
-
sentinel = lambda do |port|
|
128
|
-
{
|
129
|
-
:auth => lambda do |pass|
|
130
|
-
commands[:s1] << ["auth", pass]
|
131
|
-
"-ERR unknown command 'auth'"
|
132
|
-
end,
|
133
|
-
:select => lambda do |db|
|
134
|
-
commands[:s1] << ["select", db]
|
135
|
-
"-ERR unknown command 'select'"
|
136
|
-
end,
|
137
|
-
:sentinel => lambda do |command, *args|
|
138
|
-
commands[:s1] << [command, *args]
|
139
|
-
["127.0.0.1", port.to_s]
|
140
|
-
end
|
141
|
-
}
|
142
|
-
end
|
143
|
-
|
144
|
-
master = {
|
145
|
-
:auth => lambda do |pass|
|
146
|
-
commands[:m1] << ["auth", pass]
|
147
|
-
"+OK"
|
148
|
-
end,
|
149
|
-
:role => lambda do
|
150
|
-
commands[:m1] << ["role"]
|
151
|
-
["master"]
|
152
|
-
end
|
153
|
-
}
|
154
|
-
|
155
|
-
RedisMock.start(master) do |master_port|
|
156
|
-
RedisMock.start(sentinel.call(master_port)) do |sen_port|
|
157
|
-
sentinels[0][:port] = sen_port
|
158
|
-
redis = Redis.new(:url => "redis://:foo@master1/15", :sentinels => sentinels, :role => :master)
|
159
|
-
|
160
|
-
assert redis.ping
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
assert_equal [%w[get-master-addr-by-name master1]], commands[:s1]
|
165
|
-
assert_equal [%w[auth foo], %w[role]], commands[:m1]
|
166
|
-
end
|
167
|
-
|
168
|
-
def test_sentinel_role_mismatch
|
169
|
-
sentinels = [{:host => "127.0.0.1", :port => 26381}]
|
170
|
-
|
171
|
-
sentinel = lambda do |port|
|
172
|
-
{
|
173
|
-
:sentinel => lambda do |command, *args|
|
174
|
-
["127.0.0.1", port.to_s]
|
175
|
-
end
|
176
|
-
}
|
177
|
-
end
|
178
|
-
|
179
|
-
master = {
|
180
|
-
:role => lambda do
|
181
|
-
["slave"]
|
182
|
-
end
|
183
|
-
}
|
184
|
-
|
185
|
-
ex = assert_raise(Redis::ConnectionError) do
|
186
|
-
RedisMock.start(master) do |master_port|
|
187
|
-
RedisMock.start(sentinel.call(master_port)) do |sen_port|
|
188
|
-
sentinels[0][:port] = sen_port
|
189
|
-
redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master)
|
190
|
-
|
191
|
-
assert redis.ping
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
assert_match(/Instance role mismatch/, ex.message)
|
197
|
-
end
|
198
|
-
|
199
|
-
def test_sentinel_retries
|
200
|
-
sentinels = [{:host => "127.0.0.1", :port => 26381},
|
201
|
-
{:host => "127.0.0.1", :port => 26382}]
|
202
|
-
|
203
|
-
connections = []
|
204
|
-
|
205
|
-
handler = lambda do |id, port|
|
206
|
-
{
|
207
|
-
:sentinel => lambda do |command, *args|
|
208
|
-
connections << id
|
209
|
-
|
210
|
-
if connections.count(id) < 2
|
211
|
-
:close
|
212
|
-
else
|
213
|
-
["127.0.0.1", port.to_s]
|
214
|
-
end
|
215
|
-
end
|
216
|
-
}
|
217
|
-
end
|
218
|
-
|
219
|
-
master = {
|
220
|
-
:role => lambda do
|
221
|
-
["master"]
|
222
|
-
end
|
223
|
-
}
|
224
|
-
|
225
|
-
RedisMock.start(master) do |master_port|
|
226
|
-
RedisMock.start(handler.call(:s1, master_port)) do |s1_port|
|
227
|
-
RedisMock.start(handler.call(:s2, master_port)) do |s2_port|
|
228
|
-
sentinels[0][:port] = s1_port
|
229
|
-
sentinels[1][:port] = s2_port
|
230
|
-
redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master, :reconnect_attempts => 1)
|
231
|
-
|
232
|
-
assert redis.ping
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
assert_equal [:s1, :s2, :s1], connections
|
238
|
-
|
239
|
-
connections.clear
|
240
|
-
|
241
|
-
ex = assert_raise(Redis::CannotConnectError) do
|
242
|
-
RedisMock.start(master) do |master_port|
|
243
|
-
RedisMock.start(handler.call(:s1, master_port)) do |s1_port|
|
244
|
-
RedisMock.start(handler.call(:s2, master_port)) do |s2_port|
|
245
|
-
redis = Redis.new(:url => "redis://master1", :sentinels => sentinels, :role => :master, :reconnect_attempts => 0)
|
246
|
-
|
247
|
-
assert redis.ping
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
assert_match(/No sentinels available/, ex.message)
|
254
|
-
end
|
255
|
-
end
|
data/test/sorting_test.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
class TestSorting < Test::Unit::TestCase
|
6
|
-
|
7
|
-
include Helper::Client
|
8
|
-
|
9
|
-
def test_sort
|
10
|
-
r.set("foo:1", "s1")
|
11
|
-
r.set("foo:2", "s2")
|
12
|
-
|
13
|
-
r.rpush("bar", "1")
|
14
|
-
r.rpush("bar", "2")
|
15
|
-
|
16
|
-
assert_equal ["s1"], r.sort("bar", :get => "foo:*", :limit => [0, 1])
|
17
|
-
assert_equal ["s2"], r.sort("bar", :get => "foo:*", :limit => [0, 1], :order => "desc alpha")
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_sort_with_an_array_of_gets
|
21
|
-
r.set("foo:1:a", "s1a")
|
22
|
-
r.set("foo:1:b", "s1b")
|
23
|
-
|
24
|
-
r.set("foo:2:a", "s2a")
|
25
|
-
r.set("foo:2:b", "s2b")
|
26
|
-
|
27
|
-
r.rpush("bar", "1")
|
28
|
-
r.rpush("bar", "2")
|
29
|
-
|
30
|
-
assert_equal [["s1a", "s1b"]], r.sort("bar", :get => ["foo:*:a", "foo:*:b"], :limit => [0, 1])
|
31
|
-
assert_equal [["s2a", "s2b"]], r.sort("bar", :get => ["foo:*:a", "foo:*:b"], :limit => [0, 1], :order => "desc alpha")
|
32
|
-
assert_equal [["s1a", "s1b"], ["s2a", "s2b"]], r.sort("bar", :get => ["foo:*:a", "foo:*:b"])
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_sort_with_store
|
36
|
-
r.set("foo:1", "s1")
|
37
|
-
r.set("foo:2", "s2")
|
38
|
-
|
39
|
-
r.rpush("bar", "1")
|
40
|
-
r.rpush("bar", "2")
|
41
|
-
|
42
|
-
r.sort("bar", :get => "foo:*", :store => "baz")
|
43
|
-
assert_equal ["s1", "s2"], r.lrange("baz", 0, -1)
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_sort_with_an_array_of_gets_and_with_store
|
47
|
-
r.set("foo:1:a", "s1a")
|
48
|
-
r.set("foo:1:b", "s1b")
|
49
|
-
|
50
|
-
r.set("foo:2:a", "s2a")
|
51
|
-
r.set("foo:2:b", "s2b")
|
52
|
-
|
53
|
-
r.rpush("bar", "1")
|
54
|
-
r.rpush("bar", "2")
|
55
|
-
|
56
|
-
r.sort("bar", :get => ["foo:*:a", "foo:*:b"], :store => 'baz')
|
57
|
-
assert_equal ["s1a", "s1b", "s2a", "s2b"], r.lrange("baz", 0, -1)
|
58
|
-
end
|
59
|
-
end
|
data/test/ssl_test.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
if RUBY_VERSION >= "1.9.3"
|
4
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
5
|
-
|
6
|
-
class SslTest < Test::Unit::TestCase
|
7
|
-
|
8
|
-
include Helper::Client
|
9
|
-
|
10
|
-
driver(:ruby) do
|
11
|
-
|
12
|
-
def test_verified_ssl_connection
|
13
|
-
RedisMock.start({ :ping => proc { "+PONG" } }, ssl_server_opts("trusted")) do |port|
|
14
|
-
redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file })
|
15
|
-
assert_equal redis.ping, "PONG"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_unverified_ssl_connection
|
20
|
-
assert_raise(OpenSSL::SSL::SSLError) do
|
21
|
-
RedisMock.start({ :ping => proc { "+PONG" } }, ssl_server_opts("untrusted")) do |port|
|
22
|
-
redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file })
|
23
|
-
redis.ping
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_ssl_blocking
|
29
|
-
RedisMock.start({}, ssl_server_opts("trusted")) do |port|
|
30
|
-
redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file })
|
31
|
-
assert_equal redis.set("boom", "a" * 10_000_000), "OK"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
driver(:hiredis, :synchrony) do
|
38
|
-
|
39
|
-
def test_ssl_not_implemented_exception
|
40
|
-
assert_raise(NotImplementedError) do
|
41
|
-
RedisMock.start({ :ping => proc { "+PONG" } }, ssl_server_opts("trusted")) do |port|
|
42
|
-
redis = Redis.new(:port => port, :ssl => true, :ssl_params => { :ca_file => ssl_ca_file })
|
43
|
-
redis.ping
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def ssl_server_opts(prefix)
|
53
|
-
ssl_cert = File.join(cert_path, "#{prefix}-cert.crt")
|
54
|
-
ssl_key = File.join(cert_path, "#{prefix}-cert.key")
|
55
|
-
|
56
|
-
{
|
57
|
-
:ssl => true,
|
58
|
-
:ssl_params => {
|
59
|
-
:cert => OpenSSL::X509::Certificate.new(File.read(ssl_cert)),
|
60
|
-
:key => OpenSSL::PKey::RSA.new(File.read(ssl_key))
|
61
|
-
}
|
62
|
-
}
|
63
|
-
end
|
64
|
-
|
65
|
-
def ssl_ca_file
|
66
|
-
File.join(cert_path, "trusted-ca.crt")
|
67
|
-
end
|
68
|
-
|
69
|
-
def cert_path
|
70
|
-
File.expand_path("../support/ssl/", __FILE__)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
require "support/wire/thread"
|
@@ -1 +0,0 @@
|
|
1
|
-
require "support/wire/thread"
|
data/test/support/redis_mock.rb
DELETED
@@ -1,130 +0,0 @@
|
|
1
|
-
require "socket"
|
2
|
-
|
3
|
-
module RedisMock
|
4
|
-
class Server
|
5
|
-
def initialize(options = {}, &block)
|
6
|
-
tcp_server = TCPServer.new(options[:host] || "127.0.0.1", 0)
|
7
|
-
tcp_server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
8
|
-
|
9
|
-
if options[:ssl]
|
10
|
-
ctx = OpenSSL::SSL::SSLContext.new
|
11
|
-
|
12
|
-
ssl_params = options.fetch(:ssl_params, {})
|
13
|
-
ctx.set_params(ssl_params) unless ssl_params.empty?
|
14
|
-
|
15
|
-
@server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx)
|
16
|
-
else
|
17
|
-
@server = tcp_server
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def port
|
22
|
-
@server.addr[1]
|
23
|
-
end
|
24
|
-
|
25
|
-
def start(&block)
|
26
|
-
@thread = Thread.new { run(&block) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def shutdown
|
30
|
-
@thread.kill
|
31
|
-
end
|
32
|
-
|
33
|
-
def run
|
34
|
-
begin
|
35
|
-
loop do
|
36
|
-
session = @server.accept
|
37
|
-
|
38
|
-
begin
|
39
|
-
return if yield(session) == :exit
|
40
|
-
ensure
|
41
|
-
session.close
|
42
|
-
end
|
43
|
-
end
|
44
|
-
rescue => ex
|
45
|
-
$stderr.puts "Error running mock server: #{ex.message}"
|
46
|
-
$stderr.puts ex.backtrace
|
47
|
-
retry
|
48
|
-
ensure
|
49
|
-
@server.close
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Starts a mock Redis server in a thread.
|
55
|
-
#
|
56
|
-
# The server will use the lambda handler passed as argument to handle
|
57
|
-
# connections. For example:
|
58
|
-
#
|
59
|
-
# handler = lambda { |session| session.close }
|
60
|
-
# RedisMock.start_with_handler(handler) do
|
61
|
-
# # Every connection will be closed immediately
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
def self.start_with_handler(blk, options = {})
|
65
|
-
server = Server.new(options)
|
66
|
-
port = server.port
|
67
|
-
|
68
|
-
begin
|
69
|
-
server.start(&blk)
|
70
|
-
yield(port)
|
71
|
-
ensure
|
72
|
-
server.shutdown
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Starts a mock Redis server in a thread.
|
77
|
-
#
|
78
|
-
# The server will reply with a `+OK` to all commands, but you can
|
79
|
-
# customize it by providing a hash. For example:
|
80
|
-
#
|
81
|
-
# RedisMock.start(:ping => lambda { "+PONG" }) do |port|
|
82
|
-
# assert_equal "PONG", Redis.new(:port => port).ping
|
83
|
-
# end
|
84
|
-
#
|
85
|
-
def self.start(commands, options = {}, &blk)
|
86
|
-
handler = lambda do |session|
|
87
|
-
while line = session.gets
|
88
|
-
argv = Array.new(line[1..-3].to_i) do
|
89
|
-
bytes = session.gets[1..-3].to_i
|
90
|
-
arg = session.read(bytes)
|
91
|
-
session.read(2) # Discard \r\n
|
92
|
-
arg
|
93
|
-
end
|
94
|
-
|
95
|
-
command = argv.shift
|
96
|
-
blk = commands[command.to_sym]
|
97
|
-
blk ||= lambda { |*_| "+OK" }
|
98
|
-
|
99
|
-
response = blk.call(*argv)
|
100
|
-
|
101
|
-
# Convert a nil response to :close
|
102
|
-
response ||= :close
|
103
|
-
|
104
|
-
if response == :exit
|
105
|
-
break :exit
|
106
|
-
elsif response == :close
|
107
|
-
break :close
|
108
|
-
elsif response.is_a?(Array)
|
109
|
-
session.write("*%d\r\n" % response.size)
|
110
|
-
|
111
|
-
response.each do |resp|
|
112
|
-
if resp.is_a?(Array)
|
113
|
-
session.write("*%d\r\n" % resp.size)
|
114
|
-
resp.each do |r|
|
115
|
-
session.write("$%d\r\n%s\r\n" % [r.length, r])
|
116
|
-
end
|
117
|
-
else
|
118
|
-
session.write("$%d\r\n%s\r\n" % [resp.length, resp])
|
119
|
-
end
|
120
|
-
end
|
121
|
-
else
|
122
|
-
session.write(response)
|
123
|
-
session.write("\r\n") unless response.end_with?("\r\n")
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
start_with_handler(handler, options, &blk)
|
129
|
-
end
|
130
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
|
3
|
-
get_subject() {
|
4
|
-
if [ "$1" = "trusted" ]
|
5
|
-
then
|
6
|
-
echo "/C=IT/ST=Sicily/L=Catania/O=Redis/OU=Security/CN=127.0.0.1"
|
7
|
-
else
|
8
|
-
echo "/C=XX/ST=Untrusted/L=Evilville/O=Evil Hacker/OU=Attack Department/CN=127.0.0.1"
|
9
|
-
fi
|
10
|
-
}
|
11
|
-
|
12
|
-
# Generate two CAs: one to be considered trusted, and one that's untrusted
|
13
|
-
for type in trusted untrusted; do
|
14
|
-
rm -rf ./demoCA
|
15
|
-
mkdir -p ./demoCA
|
16
|
-
mkdir -p ./demoCA/certs
|
17
|
-
mkdir -p ./demoCA/crl
|
18
|
-
mkdir -p ./demoCA/newcerts
|
19
|
-
mkdir -p ./demoCA/private
|
20
|
-
touch ./demoCA/index.txt
|
21
|
-
|
22
|
-
openssl genrsa -out ${type}-ca.key 2048
|
23
|
-
openssl req -new -x509 -days 12500 -key ${type}-ca.key -out ${type}-ca.crt -subj "$(get_subject $type)"
|
24
|
-
openssl x509 -in ${type}-ca.crt -noout -next_serial -out ./demoCA/serial
|
25
|
-
|
26
|
-
openssl req -newkey rsa:2048 -keyout ${type}-cert.key -nodes -out ${type}-cert.req -subj "$(get_subject $type)"
|
27
|
-
openssl ca -days 12500 -cert ${type}-ca.crt -keyfile ${type}-ca.key -out ${type}-cert.crt -infiles ${type}-cert.req
|
28
|
-
rm ${type}-cert.req
|
29
|
-
done
|
30
|
-
|
31
|
-
rm -rf ./demoCA
|
@@ -1,25 +0,0 @@
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
2
|
-
MIIEIDCCAwigAwIBAgIJAM7kyjC89Qj/MA0GCSqGSIb3DQEBCwUAMGcxCzAJBgNV
|
3
|
-
BAYTAklUMQ8wDQYDVQQIEwZTaWNpbHkxEDAOBgNVBAcTB0NhdGFuaWExDjAMBgNV
|
4
|
-
BAoTBVJlZGlzMREwDwYDVQQLEwhTZWN1cml0eTESMBAGA1UEAxMJMTI3LjAuMC4x
|
5
|
-
MCAXDTE2MDQwMjAzMzQ0MVoYDzIwNTAwNjIzMDMzNDQxWjBnMQswCQYDVQQGEwJJ
|
6
|
-
VDEPMA0GA1UECBMGU2ljaWx5MRAwDgYDVQQHEwdDYXRhbmlhMQ4wDAYDVQQKEwVS
|
7
|
-
ZWRpczERMA8GA1UECxMIU2VjdXJpdHkxEjAQBgNVBAMTCTEyNy4wLjAuMTCCASIw
|
8
|
-
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMeibFqEG38mtN9DSXy6NZdd7AjH
|
9
|
-
4/D+VdDzlbJlI5IBACCV9p6P2j5PFlFvkHFE6vr6biMaLXNAmUHYfDzeT95LODHH
|
10
|
-
t+8HlR51cNYrnt9B3eiVwEnJ7+axuDHg6nUgLXeKeog+vEqreZwLnFibxt2qpFze
|
11
|
-
xzyKJ37Pm+iAey5glCc/v7ECYQ4sWVVV+ciC+sAwmZDfZXCBQtRRokJ6ikqQDwWV
|
12
|
-
DugGcV46feTpu79OmkLLM8PI3E7ow2F/3iv67gmdlO5m9wX1ahWzJKUapBTxgf4X
|
13
|
-
QG0s60WbC9iJIvgXRGW7wWSsqSVJkfLYllDTPgfpLyl1+FR3A4awrsPiMVUCAwEA
|
14
|
-
AaOBzDCByTAdBgNVHQ4EFgQU+YG9kJR3Vy31d7QVyxRAYyKTK18wgZkGA1UdIwSB
|
15
|
-
kTCBjoAU+YG9kJR3Vy31d7QVyxRAYyKTK1+ha6RpMGcxCzAJBgNVBAYTAklUMQ8w
|
16
|
-
DQYDVQQIEwZTaWNpbHkxEDAOBgNVBAcTB0NhdGFuaWExDjAMBgNVBAoTBVJlZGlz
|
17
|
-
MREwDwYDVQQLEwhTZWN1cml0eTESMBAGA1UEAxMJMTI3LjAuMC4xggkAzuTKMLz1
|
18
|
-
CP8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAeFKB7DUixmxbdvNw
|
19
|
-
n/mNoHK+OOZXmfxZDCo0v2gcQ4WXUiCqL6MagrImCvkEz5RL6Fk2ZflEV2iGQ5Ds
|
20
|
-
CmF2n47ISpqG29bfI5R1rcbfqK/5tazUIhQu12ThNmkEh7hCuW/0LqJrnmxpuRLy
|
21
|
-
le9e3svCC96lwjFczzU/utWurKt7S7Di3C4P+AXAJJuszDMLMCBLaB/3j24cNpOx
|
22
|
-
zzeZo02x4rpsD2+MMfRDWMWezVEyk63KnI0kt3JGnepsKCFc48ZOk09LwFk3Rfaq
|
23
|
-
zuKSgEJJw1mfsdBfysM0HQw20yyjSdoTEfQq3bXctTNi+pEOgW6x7TMsnngYYLXV
|
24
|
-
9XTrpg==
|
25
|
-
-----END CERTIFICATE-----
|
@@ -1,27 +0,0 @@
|
|
1
|
-
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
MIIEpQIBAAKCAQEAx6JsWoQbfya030NJfLo1l13sCMfj8P5V0POVsmUjkgEAIJX2
|
3
|
-
no/aPk8WUW+QcUTq+vpuIxotc0CZQdh8PN5P3ks4Mce37weVHnVw1iue30Hd6JXA
|
4
|
-
Scnv5rG4MeDqdSAtd4p6iD68Sqt5nAucWJvG3aqkXN7HPIonfs+b6IB7LmCUJz+/
|
5
|
-
sQJhDixZVVX5yIL6wDCZkN9lcIFC1FGiQnqKSpAPBZUO6AZxXjp95Om7v06aQssz
|
6
|
-
w8jcTujDYX/eK/ruCZ2U7mb3BfVqFbMkpRqkFPGB/hdAbSzrRZsL2Iki+BdEZbvB
|
7
|
-
ZKypJUmR8tiWUNM+B+kvKXX4VHcDhrCuw+IxVQIDAQABAoIBAQCzbGHiQJXOA+XQ
|
8
|
-
O9OSjHGaJ8n6Yl2VvaE3eZXzjj8X/Fo271GGVVgbZE10x8aUZxKim+3dEqwCx+52
|
9
|
-
ZbHTqyMxcX2CEDRaWwBFLdxKQU467iIZ5m26ZAp/1v7rpXBT8KWsqQNT7L6ihdd4
|
10
|
-
zl6orOlhVPsAlSGQYcL5kHJZ1w/fL0phEbwdISd3PYhGHXMNmqfXorzJYHDQA4R+
|
11
|
-
yR7WpP1dmnUeEKrHc9FFcBZ75BGlWjdCPZMFKc7IndZumarhBpWH9yZMUxrUIo4V
|
12
|
-
SCweRUFdD5H1lMZ0YiIAE25wKNEQ2iGd3Jfr8Vj1KFSHC9I2FJA3aFRRUgTwxx/W
|
13
|
-
h0mJy1ZJAoGBAPYsSSlwQdxZjnyZiVkNSD4MoLdof//nRxeKGejq6AiXDvcsLyJy
|
14
|
-
0MKk4YBFw2249TWm/KBbMAFiBE7d8uPtP5pPfjNVPX6VltH3AhSZ7Ugbpo6C3NFA
|
15
|
-
GpzFVtNaWgCVDloDVdmsY7ssDFuAIih0paklPAqnLY+Ua9m1BiEPrB+bAoGBAM+a
|
16
|
-
i+0NMR4AyKpuo1exdd+7BIHw5HNPwGmR1ggdGWduH0zsOhEawQKKFv1X9xKAcXxW
|
17
|
-
PyeD56/Tmn7fkWvuE8dOu9E6em0vgmxhYyn4nyLAFYF5uKXYo78MpIEThdpl1ldT
|
18
|
-
iHwG/25vunaBUHhwbHPUD+F989tmRuCjoFkuA5nPAoGAaqPIlcDhZvkMtoE0dHVC
|
19
|
-
hE6oGIuWV17y9wmGK9YG6iG2A/EKAhxGvur6HL0b6Z4j6zgJW9Xkt9SkFR4kqAQQ
|
20
|
-
d2JUQxx75SgcC5y7M/1yQrhnsHiT+7mPTbZW5HvRXUs0yl2DhSYeleiA+epJ4ciW
|
21
|
-
Mu3EUsEVBYvAJLE8lHnbkF0CgYEAhyxpz3+3a4G3JsHDOWYjCfoLhVAEb9CNyC9c
|
22
|
-
3QuVbvMVDlEBvgFdivm+3lZYWYOoYP0HQgNw59svzUxks5Hg7vUk9abN8CnvEgKX
|
23
|
-
PszTUR0g450NzW6xr8PbmO/NR9bnKRUK2Tb1OkMldePdMY6CDykU7g3EqiZ+H+Zq
|
24
|
-
kaaUUaECgYEAmk5W+S94q5jLemnfAChC5lva/0/aHdhtaoH4Lo+j0haMsdiy8/ZE
|
25
|
-
sh+3gQ8pqwaCAwnKxAcppt/FNZ7tHRsH3oyY6biypn3WppQj+BA41nuzbspOKJhR
|
26
|
-
ZDXKFCItbzUjyi23Dx4P4DgMivkpV+e88RMIuBnv4yjl5iOLq+vf4Rg=
|
27
|
-
-----END RSA PRIVATE KEY-----
|