redis 4.0.0.rc1 → 4.4.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.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +143 -3
  3. data/README.md +127 -18
  4. data/lib/redis/client.rb +150 -93
  5. data/lib/redis/cluster/command.rb +81 -0
  6. data/lib/redis/cluster/command_loader.rb +34 -0
  7. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  8. data/lib/redis/cluster/node.rb +108 -0
  9. data/lib/redis/cluster/node_key.rb +31 -0
  10. data/lib/redis/cluster/node_loader.rb +37 -0
  11. data/lib/redis/cluster/option.rb +93 -0
  12. data/lib/redis/cluster/slot.rb +86 -0
  13. data/lib/redis/cluster/slot_loader.rb +49 -0
  14. data/lib/redis/cluster.rb +291 -0
  15. data/lib/redis/connection/command_helper.rb +3 -2
  16. data/lib/redis/connection/hiredis.rb +4 -3
  17. data/lib/redis/connection/registry.rb +2 -1
  18. data/lib/redis/connection/ruby.rb +123 -105
  19. data/lib/redis/connection/synchrony.rb +18 -5
  20. data/lib/redis/connection.rb +2 -0
  21. data/lib/redis/distributed.rb +955 -0
  22. data/lib/redis/errors.rb +48 -0
  23. data/lib/redis/hash_ring.rb +89 -0
  24. data/lib/redis/pipeline.rb +55 -9
  25. data/lib/redis/subscribe.rb +11 -12
  26. data/lib/redis/version.rb +3 -1
  27. data/lib/redis.rb +1242 -381
  28. metadata +34 -141
  29. data/.gitignore +0 -16
  30. data/.travis/Gemfile +0 -11
  31. data/.travis.yml +0 -71
  32. data/.yardopts +0 -3
  33. data/Gemfile +0 -3
  34. data/benchmarking/logging.rb +0 -71
  35. data/benchmarking/pipeline.rb +0 -51
  36. data/benchmarking/speed.rb +0 -21
  37. data/benchmarking/suite.rb +0 -24
  38. data/benchmarking/worker.rb +0 -71
  39. data/examples/basic.rb +0 -15
  40. data/examples/consistency.rb +0 -114
  41. data/examples/incr-decr.rb +0 -17
  42. data/examples/list.rb +0 -26
  43. data/examples/pubsub.rb +0 -37
  44. data/examples/sentinel/sentinel.conf +0 -9
  45. data/examples/sentinel/start +0 -49
  46. data/examples/sentinel.rb +0 -41
  47. data/examples/sets.rb +0 -36
  48. data/examples/unicorn/config.ru +0 -3
  49. data/examples/unicorn/unicorn.rb +0 -20
  50. data/makefile +0 -42
  51. data/redis.gemspec +0 -40
  52. data/test/bitpos_test.rb +0 -63
  53. data/test/blocking_commands_test.rb +0 -183
  54. data/test/client_test.rb +0 -59
  55. data/test/command_map_test.rb +0 -28
  56. data/test/commands_on_hashes_test.rb +0 -174
  57. data/test/commands_on_hyper_log_log_test.rb +0 -70
  58. data/test/commands_on_lists_test.rb +0 -154
  59. data/test/commands_on_sets_test.rb +0 -208
  60. data/test/commands_on_sorted_sets_test.rb +0 -444
  61. data/test/commands_on_strings_test.rb +0 -338
  62. data/test/commands_on_value_types_test.rb +0 -246
  63. data/test/connection_handling_test.rb +0 -275
  64. data/test/db/.gitkeep +0 -0
  65. data/test/encoding_test.rb +0 -14
  66. data/test/error_replies_test.rb +0 -57
  67. data/test/fork_safety_test.rb +0 -60
  68. data/test/helper.rb +0 -179
  69. data/test/helper_test.rb +0 -22
  70. data/test/internals_test.rb +0 -435
  71. data/test/persistence_control_commands_test.rb +0 -24
  72. data/test/pipelining_commands_test.rb +0 -238
  73. data/test/publish_subscribe_test.rb +0 -280
  74. data/test/remote_server_control_commands_test.rb +0 -175
  75. data/test/scanning_test.rb +0 -407
  76. data/test/scripting_test.rb +0 -76
  77. data/test/sentinel_command_test.rb +0 -78
  78. data/test/sentinel_test.rb +0 -253
  79. data/test/sorting_test.rb +0 -57
  80. data/test/ssl_test.rb +0 -69
  81. data/test/support/connection/hiredis.rb +0 -1
  82. data/test/support/connection/ruby.rb +0 -1
  83. data/test/support/connection/synchrony.rb +0 -17
  84. data/test/support/redis_mock.rb +0 -130
  85. data/test/support/ssl/gen_certs.sh +0 -31
  86. data/test/support/ssl/trusted-ca.crt +0 -25
  87. data/test/support/ssl/trusted-ca.key +0 -27
  88. data/test/support/ssl/trusted-cert.crt +0 -81
  89. data/test/support/ssl/trusted-cert.key +0 -28
  90. data/test/support/ssl/untrusted-ca.crt +0 -26
  91. data/test/support/ssl/untrusted-ca.key +0 -27
  92. data/test/support/ssl/untrusted-cert.crt +0 -82
  93. data/test/support/ssl/untrusted-cert.key +0 -28
  94. data/test/support/wire/synchrony.rb +0 -24
  95. data/test/support/wire/thread.rb +0 -5
  96. data/test/synchrony_driver.rb +0 -85
  97. data/test/test.conf.erb +0 -9
  98. data/test/thread_safety_test.rb +0 -60
  99. data/test/transactions_test.rb +0 -262
  100. data/test/unknown_commands_test.rb +0 -12
  101. data/test/url_param_test.rb +0 -136
@@ -1,338 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestCommandsOnStrings < Test::Unit::TestCase
4
-
5
- include Helper::Client
6
-
7
- def test_set_and_get
8
- r.set("foo", "s1")
9
-
10
- assert_equal "s1", r.get("foo")
11
- end
12
-
13
- def test_set_and_get_with_newline_characters
14
- r.set("foo", "1\n")
15
-
16
- assert_equal "1\n", r.get("foo")
17
- end
18
-
19
- def test_set_and_get_with_non_string_value
20
- value = ["a", "b"]
21
-
22
- r.set("foo", value)
23
-
24
- assert_equal value.to_s, r.get("foo")
25
- end
26
-
27
- def test_set_and_get_with_ascii_characters
28
- with_external_encoding("ASCII-8BIT") do
29
- (0..255).each do |i|
30
- str = "#{i.chr}---#{i.chr}"
31
- r.set("foo", str)
32
-
33
- assert_equal str, r.get("foo")
34
- end
35
- end
36
- end
37
-
38
- def test_set_with_ex
39
- target_version "2.6.12" do
40
- r.set("foo", "bar", :ex => 2)
41
- assert_in_range 0..2, r.ttl("foo")
42
- end
43
- end
44
-
45
- def test_set_with_px
46
- target_version "2.6.12" do
47
- r.set("foo", "bar", :px => 2000)
48
- assert_in_range 0..2, r.ttl("foo")
49
- end
50
- end
51
-
52
- def test_set_with_nx
53
- target_version "2.6.12" do
54
- r.set("foo", "qux", :nx => true)
55
- assert !r.set("foo", "bar", :nx => true)
56
- assert_equal "qux", r.get("foo")
57
-
58
- r.del("foo")
59
- assert r.set("foo", "bar", :nx => true)
60
- assert_equal "bar", r.get("foo")
61
- end
62
- end
63
-
64
- def test_set_with_xx
65
- target_version "2.6.12" do
66
- r.set("foo", "qux")
67
- assert r.set("foo", "bar", :xx => true)
68
- assert_equal "bar", r.get("foo")
69
-
70
- r.del("foo")
71
- assert !r.set("foo", "bar", :xx => true)
72
- end
73
- end
74
-
75
- def test_setex
76
- assert r.setex("foo", 1, "bar")
77
- assert_equal "bar", r.get("foo")
78
- assert [0, 1].include? r.ttl("foo")
79
- end
80
-
81
- def test_setex_with_non_string_value
82
- value = ["b", "a", "r"]
83
-
84
- assert r.setex("foo", 1, value)
85
- assert_equal value.to_s, r.get("foo")
86
- assert [0, 1].include? r.ttl("foo")
87
- end
88
-
89
- def test_psetex
90
- target_version "2.5.4" do
91
- assert r.psetex("foo", 1000, "bar")
92
- assert_equal "bar", r.get("foo")
93
- assert [0, 1].include? r.ttl("foo")
94
- end
95
- end
96
-
97
- def test_psetex_with_non_string_value
98
- target_version "2.5.4" do
99
- value = ["b", "a", "r"]
100
-
101
- assert r.psetex("foo", 1000, value)
102
- assert_equal value.to_s, r.get("foo")
103
- assert [0, 1].include? r.ttl("foo")
104
- end
105
- end
106
-
107
- def test_getset
108
- r.set("foo", "bar")
109
-
110
- assert_equal "bar", r.getset("foo", "baz")
111
- assert_equal "baz", r.get("foo")
112
- end
113
-
114
- def test_getset_with_non_string_value
115
- r.set("foo", "zap")
116
-
117
- value = ["b", "a", "r"]
118
-
119
- assert_equal "zap", r.getset("foo", value)
120
- assert_equal value.to_s, r.get("foo")
121
- end
122
-
123
- def test_setnx
124
- r.set("foo", "qux")
125
- assert !r.setnx("foo", "bar")
126
- assert_equal "qux", r.get("foo")
127
-
128
- r.del("foo")
129
- assert r.setnx("foo", "bar")
130
- assert_equal "bar", r.get("foo")
131
- end
132
-
133
- def test_setnx_with_non_string_value
134
- value = ["b", "a", "r"]
135
-
136
- r.set("foo", "qux")
137
- assert !r.setnx("foo", value)
138
- assert_equal "qux", r.get("foo")
139
-
140
- r.del("foo")
141
- assert r.setnx("foo", value)
142
- assert_equal value.to_s, r.get("foo")
143
- end
144
-
145
- def test_incr
146
- assert_equal 1, r.incr("foo")
147
- assert_equal 2, r.incr("foo")
148
- assert_equal 3, r.incr("foo")
149
- end
150
-
151
- def test_incrby
152
- assert_equal 1, r.incrby("foo", 1)
153
- assert_equal 3, r.incrby("foo", 2)
154
- assert_equal 6, r.incrby("foo", 3)
155
- end
156
-
157
- def test_incrbyfloat
158
- target_version "2.5.4" do
159
- assert_equal 1.23, r.incrbyfloat("foo", 1.23)
160
- assert_equal 2 , r.incrbyfloat("foo", 0.77)
161
- assert_equal 1.9 , r.incrbyfloat("foo", -0.1)
162
- end
163
- end
164
-
165
- def test_decr
166
- r.set("foo", 3)
167
-
168
- assert_equal 2, r.decr("foo")
169
- assert_equal 1, r.decr("foo")
170
- assert_equal 0, r.decr("foo")
171
- end
172
-
173
- def test_decrby
174
- r.set("foo", 6)
175
-
176
- assert_equal 3, r.decrby("foo", 3)
177
- assert_equal 1, r.decrby("foo", 2)
178
- assert_equal 0, r.decrby("foo", 1)
179
- end
180
-
181
- def test_append
182
- r.set "foo", "s"
183
- r.append "foo", "1"
184
-
185
- assert_equal "s1", r.get("foo")
186
- end
187
-
188
- def test_getbit
189
- r.set("foo", "a")
190
-
191
- assert_equal 1, r.getbit("foo", 1)
192
- assert_equal 1, r.getbit("foo", 2)
193
- assert_equal 0, r.getbit("foo", 3)
194
- assert_equal 0, r.getbit("foo", 4)
195
- assert_equal 0, r.getbit("foo", 5)
196
- assert_equal 0, r.getbit("foo", 6)
197
- assert_equal 1, r.getbit("foo", 7)
198
- end
199
-
200
- def test_setbit
201
- r.set("foo", "a")
202
-
203
- r.setbit("foo", 6, 1)
204
-
205
- assert_equal "c", r.get("foo")
206
- end
207
-
208
- def test_bitcount
209
- target_version "2.5.10" do
210
- r.set("foo", "abcde")
211
-
212
- assert_equal 10, r.bitcount("foo", 1, 3)
213
- assert_equal 17, r.bitcount("foo", 0, -1)
214
- end
215
- end
216
-
217
- def test_getrange
218
- r.set("foo", "abcde")
219
-
220
- assert_equal "bcd", r.getrange("foo", 1, 3)
221
- assert_equal "abcde", r.getrange("foo", 0, -1)
222
- end
223
-
224
- def test_setrange
225
- r.set("foo", "abcde")
226
-
227
- r.setrange("foo", 1, "bar")
228
-
229
- assert_equal "abare", r.get("foo")
230
- end
231
-
232
- def test_setrange_with_non_string_value
233
- r.set("foo", "abcde")
234
-
235
- value = ["b", "a", "r"]
236
-
237
- r.setrange("foo", 2, value)
238
-
239
- assert_equal "ab#{value.to_s}", r.get("foo")
240
- end
241
-
242
- def test_strlen
243
- r.set "foo", "lorem"
244
-
245
- assert_equal 5, r.strlen("foo")
246
- end
247
-
248
- def test_mget
249
- r.set("foo", "s1")
250
- r.set("bar", "s2")
251
-
252
- assert_equal ["s1", "s2"] , r.mget("foo", "bar")
253
- assert_equal ["s1", "s2", nil], r.mget("foo", "bar", "baz")
254
- end
255
-
256
- def test_mget_mapped
257
- r.set("foo", "s1")
258
- r.set("bar", "s2")
259
-
260
- response = r.mapped_mget("foo", "bar")
261
-
262
- assert_equal "s1", response["foo"]
263
- assert_equal "s2", response["bar"]
264
-
265
- response = r.mapped_mget("foo", "bar", "baz")
266
-
267
- assert_equal "s1", response["foo"]
268
- assert_equal "s2", response["bar"]
269
- assert_equal nil , response["baz"]
270
- end
271
-
272
- def test_mapped_mget_in_a_pipeline_returns_hash
273
- r.set("foo", "s1")
274
- r.set("bar", "s2")
275
-
276
- result = r.pipelined do
277
- r.mapped_mget("foo", "bar")
278
- end
279
-
280
- assert_equal result[0], { "foo" => "s1", "bar" => "s2" }
281
- end
282
-
283
- def test_mset
284
- r.mset(:foo, "s1", :bar, "s2")
285
-
286
- assert_equal "s1", r.get("foo")
287
- assert_equal "s2", r.get("bar")
288
- end
289
-
290
- def test_mset_mapped
291
- r.mapped_mset(:foo => "s1", :bar => "s2")
292
-
293
- assert_equal "s1", r.get("foo")
294
- assert_equal "s2", r.get("bar")
295
- end
296
-
297
- def test_msetnx
298
- r.set("foo", "s1")
299
- assert_equal false, r.msetnx(:foo, "s2", :bar, "s3")
300
- assert_equal "s1", r.get("foo")
301
- assert_equal nil, r.get("bar")
302
-
303
- r.del("foo")
304
- assert_equal true, r.msetnx(:foo, "s2", :bar, "s3")
305
- assert_equal "s2", r.get("foo")
306
- assert_equal "s3", r.get("bar")
307
- end
308
-
309
- def test_msetnx_mapped
310
- r.set("foo", "s1")
311
- assert_equal false, r.mapped_msetnx(:foo => "s2", :bar => "s3")
312
- assert_equal "s1", r.get("foo")
313
- assert_equal nil, r.get("bar")
314
-
315
- r.del("foo")
316
- assert_equal true, r.mapped_msetnx(:foo => "s2", :bar => "s3")
317
- assert_equal "s2", r.get("foo")
318
- assert_equal "s3", r.get("bar")
319
- end
320
-
321
- def test_bitop
322
- with_external_encoding("UTF-8") do
323
- target_version "2.5.10" do
324
- r.set("foo", "a")
325
- r.set("bar", "b")
326
-
327
- r.bitop(:and, "foo&bar", "foo", "bar")
328
- assert_equal "\x60", r.get("foo&bar")
329
- r.bitop(:or, "foo|bar", "foo", "bar")
330
- assert_equal "\x63", r.get("foo|bar")
331
- r.bitop(:xor, "foo^bar", "foo", "bar")
332
- assert_equal "\x03", r.get("foo^bar")
333
- r.bitop(:not, "~foo", "foo")
334
- assert_equal "\x9E", r.get("~foo")
335
- end
336
- end
337
- end
338
- end
@@ -1,246 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestCommandsOnValueTypes < Test::Unit::TestCase
4
-
5
- include Helper::Client
6
-
7
- def test_exists
8
- assert_equal false, r.exists("foo")
9
-
10
- r.set("foo", "s1")
11
-
12
- assert_equal true, r.exists("foo")
13
- end
14
-
15
- def test_type
16
- assert_equal "none", r.type("foo")
17
-
18
- r.set("foo", "s1")
19
-
20
- assert_equal "string", r.type("foo")
21
- end
22
-
23
- def test_keys
24
- r.set("f", "s1")
25
- r.set("fo", "s2")
26
- r.set("foo", "s3")
27
-
28
- assert_equal ["f","fo", "foo"], r.keys("f*").sort
29
- end
30
-
31
- def test_expire
32
- r.set("foo", "s1")
33
- assert r.expire("foo", 2)
34
- assert_in_range 0..2, r.ttl("foo")
35
- end
36
-
37
- def test_pexpire
38
- target_version "2.5.4" do
39
- r.set("foo", "s1")
40
- assert r.pexpire("foo", 2000)
41
- assert_in_range 0..2, r.ttl("foo")
42
- end
43
- end
44
-
45
- def test_expireat
46
- r.set("foo", "s1")
47
- assert r.expireat("foo", (Time.now + 2).to_i)
48
- assert_in_range 0..2, r.ttl("foo")
49
- end
50
-
51
- def test_pexpireat
52
- target_version "2.5.4" do
53
- r.set("foo", "s1")
54
- assert r.pexpireat("foo", (Time.now + 2).to_i * 1_000)
55
- assert_in_range 0..2, r.ttl("foo")
56
- end
57
- end
58
-
59
- def test_persist
60
- r.set("foo", "s1")
61
- r.expire("foo", 1)
62
- r.persist("foo")
63
-
64
- assert(-1 == r.ttl("foo"))
65
- end
66
-
67
- def test_ttl
68
- r.set("foo", "s1")
69
- r.expire("foo", 2)
70
- assert_in_range 0..2, r.ttl("foo")
71
- end
72
-
73
- def test_pttl
74
- target_version "2.5.4" do
75
- r.set("foo", "s1")
76
- r.expire("foo", 2)
77
- assert_in_range 1..2000, r.pttl("foo")
78
- end
79
- end
80
-
81
- def test_dump_and_restore
82
- target_version "2.5.7" do
83
- r.set("foo", "a")
84
- v = r.dump("foo")
85
- r.del("foo")
86
-
87
- assert r.restore("foo", 1000, v)
88
- assert_equal "a", r.get("foo")
89
- assert [0, 1].include? r.ttl("foo")
90
-
91
- r.rpush("bar", ["b", "c", "d"])
92
- w = r.dump("bar")
93
- r.del("bar")
94
-
95
- assert r.restore("bar", 1000, w)
96
- assert_equal ["b", "c", "d"], r.lrange("bar", 0, -1)
97
- assert [0, 1].include? r.ttl("bar")
98
- end
99
- end
100
-
101
- def test_move
102
- r.select 14
103
- r.flushdb
104
-
105
- r.set "bar", "s3"
106
-
107
- r.select 15
108
-
109
- r.set "foo", "s1"
110
- r.set "bar", "s2"
111
-
112
- assert r.move("foo", 14)
113
- assert_equal nil, r.get("foo")
114
-
115
- assert !r.move("bar", 14)
116
- assert_equal "s2", r.get("bar")
117
-
118
- r.select 14
119
-
120
- assert_equal "s1", r.get("foo")
121
- assert_equal "s3", r.get("bar")
122
- end
123
-
124
- def test_del
125
- r.set "foo", "s1"
126
- r.set "bar", "s2"
127
- r.set "baz", "s3"
128
-
129
- assert_equal ["bar", "baz", "foo"], r.keys("*").sort
130
-
131
- assert_equal 1, r.del("foo")
132
-
133
- assert_equal ["bar", "baz"], r.keys("*").sort
134
-
135
- assert_equal 2, r.del("bar", "baz")
136
-
137
- assert_equal [], r.keys("*").sort
138
- end
139
-
140
- def test_del_with_array_argument
141
- r.set "foo", "s1"
142
- r.set "bar", "s2"
143
- r.set "baz", "s3"
144
-
145
- assert_equal ["bar", "baz", "foo"], r.keys("*").sort
146
-
147
- assert_equal 1, r.del(["foo"])
148
-
149
- assert_equal ["bar", "baz"], r.keys("*").sort
150
-
151
- assert_equal 2, r.del(["bar", "baz"])
152
-
153
- assert_equal [], r.keys("*").sort
154
- end
155
-
156
- def test_randomkey
157
- assert r.randomkey.to_s.empty?
158
-
159
- r.set("foo", "s1")
160
-
161
- assert_equal "foo", r.randomkey
162
-
163
- r.set("bar", "s2")
164
-
165
- 4.times do
166
- assert ["foo", "bar"].include?(r.randomkey)
167
- end
168
- end
169
-
170
- def test_rename
171
- r.set("foo", "s1")
172
- r.rename "foo", "bar"
173
-
174
- assert_equal "s1", r.get("bar")
175
- assert_equal nil, r.get("foo")
176
- end
177
-
178
- def test_renamenx
179
- r.set("foo", "s1")
180
- r.set("bar", "s2")
181
-
182
- assert_equal false, r.renamenx("foo", "bar")
183
-
184
- assert_equal "s1", r.get("foo")
185
- assert_equal "s2", r.get("bar")
186
- end
187
-
188
- def test_dbsize
189
- assert_equal 0, r.dbsize
190
-
191
- r.set("foo", "s1")
192
-
193
- assert_equal 1, r.dbsize
194
- end
195
-
196
- def test_flushdb
197
- r.set("foo", "s1")
198
- r.set("bar", "s2")
199
-
200
- assert_equal 2, r.dbsize
201
-
202
- r.flushdb
203
-
204
- assert_equal 0, r.dbsize
205
- end
206
-
207
- def test_flushall
208
- redis_mock(:flushall => lambda { "+FLUSHALL" }) do |redis|
209
- assert_equal "FLUSHALL", redis.flushall
210
- end
211
- end
212
-
213
- def test_migrate
214
- redis_mock(:migrate => lambda { |*args| args }) do |redis|
215
- options = { :host => "127.0.0.1", :port => 1234 }
216
-
217
- ex = assert_raise(RuntimeError) do
218
- redis.migrate("foo", options.reject { |key, _| key == :host })
219
- end
220
- assert ex.message =~ /host not specified/
221
-
222
- ex = assert_raise(RuntimeError) do
223
- redis.migrate("foo", options.reject { |key, _| key == :port })
224
- end
225
- assert ex.message =~ /port not specified/
226
-
227
- default_db = redis._client.db.to_i
228
- default_timeout = redis._client.timeout.to_i
229
-
230
- # Test defaults
231
- actual = redis.migrate("foo", options)
232
- expected = ["127.0.0.1", "1234", "foo", default_db.to_s, default_timeout.to_s]
233
- assert_equal expected, actual
234
-
235
- # Test db override
236
- actual = redis.migrate("foo", options.merge(:db => default_db + 1))
237
- expected = ["127.0.0.1", "1234", "foo", (default_db + 1).to_s, default_timeout.to_s]
238
- assert_equal expected, actual
239
-
240
- # Test timeout override
241
- actual = redis.migrate("foo", options.merge(:timeout => default_timeout + 1))
242
- expected = ["127.0.0.1", "1234", "foo", default_db.to_s, (default_timeout + 1).to_s]
243
- assert_equal expected, actual
244
- end
245
- end
246
- end