redis 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.order +6 -5
- data/.travis.yml +1 -1
- data/CHANGELOG.md +20 -1
- data/benchmarking/logging.rb +10 -1
- data/lib/redis.rb +68 -13
- data/lib/redis/client.rb +13 -5
- data/lib/redis/connection/ruby.rb +13 -7
- data/lib/redis/distributed.rb +24 -2
- data/lib/redis/hash_ring.rb +2 -2
- data/lib/redis/subscribe.rb +5 -2
- data/lib/redis/version.rb +1 -1
- data/test/commands_on_strings_test.rb +16 -0
- data/test/distributed_commands_on_strings_test.rb +11 -0
- data/test/distributed_commands_requiring_clustering_test.rb +16 -0
- data/test/distributed_remote_server_control_commands_test.rb +2 -2
- data/test/helper.rb +1 -1
- data/test/helper_test.rb +7 -5
- data/test/internals_test.rb +1 -1
- data/test/lint/blocking_commands.rb +26 -0
- data/test/lint/sets.rb +29 -0
- data/test/lint/strings.rb +70 -4
- data/test/lint/value_types.rb +20 -0
- data/test/publish_subscribe_test.rb +0 -2
- data/test/test.conf +1 -1
- metadata +2 -2
data/.order
CHANGED
@@ -22,7 +22,8 @@
|
|
22
22
|
"slaveof",
|
23
23
|
"slowlog",
|
24
24
|
"sync",
|
25
|
-
"time"
|
25
|
+
"time",
|
26
|
+
"client"
|
26
27
|
],
|
27
28
|
"generic": [
|
28
29
|
"persist",
|
@@ -70,7 +71,8 @@
|
|
70
71
|
"append",
|
71
72
|
"bitcount",
|
72
73
|
"getset",
|
73
|
-
"strlen"
|
74
|
+
"strlen",
|
75
|
+
"bitop"
|
74
76
|
],
|
75
77
|
"list": [
|
76
78
|
"llen",
|
@@ -90,8 +92,7 @@
|
|
90
92
|
"lrange",
|
91
93
|
"lrem",
|
92
94
|
"lset",
|
93
|
-
"ltrim"
|
94
|
-
"bitop"
|
95
|
+
"ltrim"
|
95
96
|
],
|
96
97
|
"set": [
|
97
98
|
"scard",
|
@@ -166,4 +167,4 @@
|
|
166
167
|
"eval",
|
167
168
|
"evalsha"
|
168
169
|
]
|
169
|
-
}
|
170
|
+
}
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,23 @@
|
|
1
|
-
# 3.0.
|
1
|
+
# 3.0.4 (unreleased)
|
2
|
+
|
3
|
+
* ...
|
4
|
+
|
5
|
+
# 3.0.3
|
6
|
+
|
7
|
+
* Blocking list commands (`BLPOP`, `BRPOP`, `BRPOPLPUSH`) use a socket
|
8
|
+
timeout equal to the sum of the command's timeout and the Redis
|
9
|
+
client's timeout, instead of disabling socket timeout altogether.
|
10
|
+
|
11
|
+
* Ruby 2.0 compatibility.
|
12
|
+
|
13
|
+
* Added support for `DUMP` and `RESTORE` (Redis 2.6).
|
14
|
+
|
15
|
+
* Added support for `BITCOUNT` and `BITOP` (Redis 2.6).
|
16
|
+
|
17
|
+
* Call `#to_s` on value argument for `SET`, `SETEX`, `PSETEX`, `GETSET`,
|
18
|
+
`SETNX`, and `SETRANGE`.
|
19
|
+
|
20
|
+
# 3.0.2
|
2
21
|
|
3
22
|
* Unescape CGI escaped password in URL.
|
4
23
|
|
data/benchmarking/logging.rb
CHANGED
@@ -54,7 +54,16 @@ benchmark "Default options (no logger)" do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
logging_redises.each do |redis|
|
57
|
-
|
57
|
+
logger = redis.client.logger
|
58
|
+
|
59
|
+
case logger
|
60
|
+
when Logger
|
61
|
+
level = Logger::SEV_LABEL[logger.level]
|
62
|
+
when Log4r::Logger
|
63
|
+
level = logger.levels[logger.level]
|
64
|
+
end
|
65
|
+
|
66
|
+
benchmark "#{logger.class} on #{level}" do
|
58
67
|
stress(redis)
|
59
68
|
end
|
60
69
|
end
|
data/lib/redis.rb
CHANGED
@@ -181,7 +181,7 @@ class Redis
|
|
181
181
|
if reply.kind_of?(String)
|
182
182
|
reply = Hash[reply.split("\r\n").map do |line|
|
183
183
|
line.split(":", 2) unless line =~ /^(#|$)/
|
184
|
-
end]
|
184
|
+
end.compact]
|
185
185
|
|
186
186
|
if cmd && cmd.to_s == "commandstats"
|
187
187
|
# Extract nested hashes for INFO COMMANDSTATS
|
@@ -359,6 +359,28 @@ class Redis
|
|
359
359
|
end
|
360
360
|
end
|
361
361
|
|
362
|
+
# Return a serialized version of the value stored at a key.
|
363
|
+
#
|
364
|
+
# @param [String] key
|
365
|
+
# @return [String] serialized_value
|
366
|
+
def dump(key)
|
367
|
+
synchronize do |client|
|
368
|
+
client.call([:dump, key])
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
# Create a key using the serialized value, previously obtained using DUMP.
|
373
|
+
#
|
374
|
+
# @param [String] key
|
375
|
+
# @param [String] ttl
|
376
|
+
# @param [String] serialized_value
|
377
|
+
# @return `"OK"`
|
378
|
+
def restore(key, ttl, serialized_value)
|
379
|
+
synchronize do |client|
|
380
|
+
client.call([:restore, key, ttl, serialized_value])
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
362
384
|
# Delete one or more keys.
|
363
385
|
#
|
364
386
|
# @param [String, Array<String>] keys
|
@@ -605,7 +627,7 @@ class Redis
|
|
605
627
|
# @return `"OK"`
|
606
628
|
def set(key, value)
|
607
629
|
synchronize do |client|
|
608
|
-
client.call([:set, key, value])
|
630
|
+
client.call([:set, key, value.to_s])
|
609
631
|
end
|
610
632
|
end
|
611
633
|
|
@@ -619,7 +641,7 @@ class Redis
|
|
619
641
|
# @return `"OK"`
|
620
642
|
def setex(key, ttl, value)
|
621
643
|
synchronize do |client|
|
622
|
-
client.call([:setex, key, ttl, value])
|
644
|
+
client.call([:setex, key, ttl, value.to_s])
|
623
645
|
end
|
624
646
|
end
|
625
647
|
|
@@ -631,7 +653,7 @@ class Redis
|
|
631
653
|
# @return `"OK"`
|
632
654
|
def psetex(key, ttl, value)
|
633
655
|
synchronize do |client|
|
634
|
-
client.call([:psetex, key, ttl, value])
|
656
|
+
client.call([:psetex, key, ttl, value.to_s])
|
635
657
|
end
|
636
658
|
end
|
637
659
|
|
@@ -642,7 +664,7 @@ class Redis
|
|
642
664
|
# @return [Boolean] whether the key was set or not
|
643
665
|
def setnx(key, value)
|
644
666
|
synchronize do |client|
|
645
|
-
client.call([:setnx, key, value], &_boolify)
|
667
|
+
client.call([:setnx, key, value.to_s], &_boolify)
|
646
668
|
end
|
647
669
|
end
|
648
670
|
|
@@ -762,7 +784,7 @@ class Redis
|
|
762
784
|
# @return [Fixnum] length of the string after it was modified
|
763
785
|
def setrange(key, offset, value)
|
764
786
|
synchronize do |client|
|
765
|
-
client.call([:setrange, key, offset, value])
|
787
|
+
client.call([:setrange, key, offset, value.to_s])
|
766
788
|
end
|
767
789
|
end
|
768
790
|
|
@@ -813,6 +835,30 @@ class Redis
|
|
813
835
|
end
|
814
836
|
end
|
815
837
|
|
838
|
+
# Count the number of set bits in a range of the string value stored at key.
|
839
|
+
#
|
840
|
+
# @param [String] key
|
841
|
+
# @param [Fixnum] start start index
|
842
|
+
# @param [Fixnum] stop stop index
|
843
|
+
# @return [Fixnum] the number of bits set to 1
|
844
|
+
def bitcount(key, start = 0, stop = -1)
|
845
|
+
synchronize do |client|
|
846
|
+
client.call([:bitcount, key, start, stop])
|
847
|
+
end
|
848
|
+
end
|
849
|
+
|
850
|
+
# Perform a bitwise operation between strings and store the resulting string in a key.
|
851
|
+
#
|
852
|
+
# @param [String] operation e.g. `and`, `or`, `xor`, `not`
|
853
|
+
# @param [String] destkey destination key
|
854
|
+
# @param [String, Array<String>] keys one or more source keys to perform `operation`
|
855
|
+
# @return [Fixnum] the length of the string stored in `destkey`
|
856
|
+
def bitop(operation, destkey, *keys)
|
857
|
+
synchronize do |client|
|
858
|
+
client.call([:bitop, operation, destkey] + keys)
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
816
862
|
# Set the string value of a key and return its old value.
|
817
863
|
#
|
818
864
|
# @param [String] key
|
@@ -821,7 +867,7 @@ class Redis
|
|
821
867
|
# did not exist
|
822
868
|
def getset(key, value)
|
823
869
|
synchronize do |client|
|
824
|
-
client.call([:getset, key, value])
|
870
|
+
client.call([:getset, key, value.to_s])
|
825
871
|
end
|
826
872
|
end
|
827
873
|
|
@@ -849,7 +895,7 @@ class Redis
|
|
849
895
|
# Prepend one or more values to a list, creating the list if it doesn't exist
|
850
896
|
#
|
851
897
|
# @param [String] key
|
852
|
-
# @param [String] value
|
898
|
+
# @param [String, Array] string value, or array of string values to push
|
853
899
|
# @return [Fixnum] the length of the list after the push operation
|
854
900
|
def lpush(key, value)
|
855
901
|
synchronize do |client|
|
@@ -940,7 +986,9 @@ class Redis
|
|
940
986
|
timeout = options[:timeout] || 0
|
941
987
|
|
942
988
|
synchronize do |client|
|
943
|
-
|
989
|
+
command = [cmd, keys, timeout]
|
990
|
+
timeout += client.timeout if timeout > 0
|
991
|
+
client.call_with_timeout(command, timeout)
|
944
992
|
end
|
945
993
|
end
|
946
994
|
|
@@ -1006,7 +1054,9 @@ class Redis
|
|
1006
1054
|
timeout = options[:timeout] || 0
|
1007
1055
|
|
1008
1056
|
synchronize do |client|
|
1009
|
-
|
1057
|
+
command = [:brpoplpush, source, destination, timeout]
|
1058
|
+
timeout += client.timeout if timeout > 0
|
1059
|
+
client.call_with_timeout(command, timeout)
|
1010
1060
|
end
|
1011
1061
|
end
|
1012
1062
|
|
@@ -1150,13 +1200,18 @@ class Redis
|
|
1150
1200
|
end
|
1151
1201
|
end
|
1152
1202
|
|
1153
|
-
# Get
|
1203
|
+
# Get one or more random members from a set.
|
1154
1204
|
#
|
1155
1205
|
# @param [String] key
|
1206
|
+
# @param [Fixnum] count
|
1156
1207
|
# @return [String]
|
1157
|
-
def srandmember(key)
|
1208
|
+
def srandmember(key, count = nil)
|
1158
1209
|
synchronize do |client|
|
1159
|
-
|
1210
|
+
if count.nil?
|
1211
|
+
client.call([:srandmember, key])
|
1212
|
+
else
|
1213
|
+
client.call([:srandmember, key, count])
|
1214
|
+
end
|
1160
1215
|
end
|
1161
1216
|
end
|
1162
1217
|
|
data/lib/redis/client.rb
CHANGED
@@ -160,14 +160,18 @@ class Redis
|
|
160
160
|
result
|
161
161
|
end
|
162
162
|
|
163
|
-
def
|
164
|
-
|
163
|
+
def call_with_timeout(command, timeout, &blk)
|
164
|
+
with_socket_timeout(timeout) do
|
165
165
|
call(command, &blk)
|
166
166
|
end
|
167
167
|
rescue ConnectionError
|
168
168
|
retry
|
169
169
|
end
|
170
170
|
|
171
|
+
def call_without_timeout(command, &blk)
|
172
|
+
call_with_timeout(command, 0, &blk)
|
173
|
+
end
|
174
|
+
|
171
175
|
def process(commands)
|
172
176
|
logging(commands) do
|
173
177
|
ensure_connected do
|
@@ -218,17 +222,21 @@ class Redis
|
|
218
222
|
end
|
219
223
|
end
|
220
224
|
|
221
|
-
def
|
225
|
+
def with_socket_timeout(timeout)
|
222
226
|
connect unless connected?
|
223
227
|
|
224
228
|
begin
|
225
|
-
connection.timeout =
|
229
|
+
connection.timeout = timeout
|
226
230
|
yield
|
227
231
|
ensure
|
228
|
-
connection.timeout = timeout if connected?
|
232
|
+
connection.timeout = self.timeout if connected?
|
229
233
|
end
|
230
234
|
end
|
231
235
|
|
236
|
+
def without_socket_timeout(&blk)
|
237
|
+
with_socket_timeout(0, &blk)
|
238
|
+
end
|
239
|
+
|
232
240
|
def with_reconnect(val=true)
|
233
241
|
begin
|
234
242
|
original, @reconnect = @reconnect, val
|
@@ -83,11 +83,7 @@ class Redis
|
|
83
83
|
|
84
84
|
class UNIXSocket < ::UNIXSocket
|
85
85
|
|
86
|
-
|
87
|
-
# Errno::EAGAIN on #read_nonblock even when IO.select says it is
|
88
|
-
# readable. This behavior shows in 1.6.6 in both 1.8 and 1.9 mode.
|
89
|
-
# Therefore, fall back on the default Unix socket implementation,
|
90
|
-
# without timeouts.
|
86
|
+
include SocketMixin
|
91
87
|
|
92
88
|
def self.connect(path, timeout)
|
93
89
|
Timeout.timeout(timeout) do
|
@@ -97,6 +93,17 @@ class Redis
|
|
97
93
|
rescue Timeout::Error
|
98
94
|
raise TimeoutError
|
99
95
|
end
|
96
|
+
|
97
|
+
# JRuby raises Errno::EAGAIN on #read_nonblock even when IO.select
|
98
|
+
# says it is readable (1.6.6, in both 1.8 and 1.9 mode).
|
99
|
+
# Use the blocking #readpartial method instead.
|
100
|
+
|
101
|
+
def _read_from_socket(nbytes)
|
102
|
+
readpartial(nbytes)
|
103
|
+
|
104
|
+
rescue EOFError
|
105
|
+
raise Errno::ECONNRESET
|
106
|
+
end
|
100
107
|
end
|
101
108
|
|
102
109
|
end
|
@@ -132,8 +139,7 @@ class Redis
|
|
132
139
|
|
133
140
|
class UNIXSocket < ::Socket
|
134
141
|
|
135
|
-
|
136
|
-
# with the JRuby implementation.
|
142
|
+
include SocketMixin
|
137
143
|
|
138
144
|
def self.connect(path, timeout)
|
139
145
|
sock = new(::Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
|
data/lib/redis/distributed.rb
CHANGED
@@ -137,6 +137,16 @@ class Redis
|
|
137
137
|
node_for(key).pttl(key)
|
138
138
|
end
|
139
139
|
|
140
|
+
# Return a serialized version of the value stored at a key.
|
141
|
+
def dump(key)
|
142
|
+
node_for(key).dump(key)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Create a key using the serialized value, previously obtained using DUMP.
|
146
|
+
def restore(key, ttl, serialized_value)
|
147
|
+
node_for(key).restore(key, ttl, serialized_value)
|
148
|
+
end
|
149
|
+
|
140
150
|
# Delete a key.
|
141
151
|
def del(*args)
|
142
152
|
keys_per_node = args.group_by { |key| node_for(key) }
|
@@ -295,6 +305,18 @@ class Redis
|
|
295
305
|
node_for(key).append(key, value)
|
296
306
|
end
|
297
307
|
|
308
|
+
# Count the number of set bits in a range of the string value stored at key.
|
309
|
+
def bitcount(key, start = 0, stop = -1)
|
310
|
+
node_for(key).bitcount(key, start, stop)
|
311
|
+
end
|
312
|
+
|
313
|
+
# Perform a bitwise operation between strings and store the resulting string in a key.
|
314
|
+
def bitop(operation, destkey, *keys)
|
315
|
+
ensure_same_node(:bitop, [destkey] + keys) do |node|
|
316
|
+
node.bitop(operation, destkey, *keys)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
298
320
|
# Set the string value of a key and return its old value.
|
299
321
|
def getset(key, value)
|
300
322
|
node_for(key).getset(key, value)
|
@@ -455,8 +477,8 @@ class Redis
|
|
455
477
|
end
|
456
478
|
|
457
479
|
# Get a random member from a set.
|
458
|
-
def srandmember(key)
|
459
|
-
node_for(key).srandmember(key)
|
480
|
+
def srandmember(key, count = nil)
|
481
|
+
node_for(key).srandmember(key, count)
|
460
482
|
end
|
461
483
|
|
462
484
|
# Move a member from one set to another.
|
data/lib/redis/hash_ring.rb
CHANGED
data/lib/redis/subscribe.rb
CHANGED
@@ -29,14 +29,17 @@ class Redis
|
|
29
29
|
def subscription(start, stop, channels, block)
|
30
30
|
sub = Subscription.new(&block)
|
31
31
|
|
32
|
+
unsubscribed = false
|
33
|
+
|
32
34
|
begin
|
33
35
|
@client.call_loop([start, *channels]) do |line|
|
34
36
|
type, *rest = line
|
35
37
|
sub.callbacks[type].call(*rest)
|
36
|
-
|
38
|
+
unsubscribed = type == stop && rest.last == 0
|
39
|
+
break if unsubscribed
|
37
40
|
end
|
38
41
|
ensure
|
39
|
-
send(stop)
|
42
|
+
send(stop) if !unsubscribed
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
data/lib/redis/version.rb
CHANGED
@@ -80,4 +80,20 @@ class TestCommandsOnStrings < Test::Unit::TestCase
|
|
80
80
|
assert_equal "s2", r.get("foo")
|
81
81
|
assert_equal "s3", r.get("bar")
|
82
82
|
end
|
83
|
+
|
84
|
+
def test_bitop
|
85
|
+
return if version < "2.5.10"
|
86
|
+
|
87
|
+
r.set("foo", "a")
|
88
|
+
r.set("bar", "b")
|
89
|
+
|
90
|
+
r.bitop(:and, "foo&bar", "foo", "bar")
|
91
|
+
assert_equal "\x60", r.get("foo&bar")
|
92
|
+
r.bitop(:or, "foo|bar", "foo", "bar")
|
93
|
+
assert_equal "\x63", r.get("foo|bar")
|
94
|
+
r.bitop(:xor, "foo^bar", "foo", "bar")
|
95
|
+
assert_equal "\x03", r.get("foo^bar")
|
96
|
+
r.bitop(:not, "~foo", "foo")
|
97
|
+
assert_equal "\x9E", r.get("~foo")
|
98
|
+
end
|
83
99
|
end
|
@@ -45,4 +45,15 @@ class TestDistributedCommandsOnStrings < Test::Unit::TestCase
|
|
45
45
|
r.mapped_msetnx(:foo => "s2", :bar => "s3")
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
def test_bitop
|
50
|
+
return if version < "2.5.10"
|
51
|
+
|
52
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
53
|
+
r.set("foo", "a")
|
54
|
+
r.set("bar", "b")
|
55
|
+
|
56
|
+
r.bitop(:and, "foo&bar", "foo", "bar")
|
57
|
+
end
|
58
|
+
end
|
48
59
|
end
|
@@ -145,4 +145,20 @@ class TestDistributedCommandsRequiringClustering < Test::Unit::TestCase
|
|
145
145
|
r.sort("{qux}bar", :get => "{qux}foo:*", :store => "{qux}baz")
|
146
146
|
assert_equal ["s1", "s2"], r.lrange("{qux}baz", 0, -1)
|
147
147
|
end
|
148
|
+
|
149
|
+
def test_bitop
|
150
|
+
return if version < "2.5.10"
|
151
|
+
|
152
|
+
r.set("{qux}foo", "a")
|
153
|
+
r.set("{qux}bar", "b")
|
154
|
+
|
155
|
+
r.bitop(:and, "{qux}foo&bar", "{qux}foo", "{qux}bar")
|
156
|
+
assert_equal "\x60", r.get("{qux}foo&bar")
|
157
|
+
r.bitop(:or, "{qux}foo|bar", "{qux}foo", "{qux}bar")
|
158
|
+
assert_equal "\x63", r.get("{qux}foo|bar")
|
159
|
+
r.bitop(:xor, "{qux}foo^bar", "{qux}foo", "{qux}bar")
|
160
|
+
assert_equal "\x03", r.get("{qux}foo^bar")
|
161
|
+
r.bitop(:not, "{qux}~foo", "{qux}foo")
|
162
|
+
assert_equal "\x9E", r.get("{qux}~foo")
|
163
|
+
end
|
148
164
|
end
|
@@ -17,9 +17,9 @@ class TestDistributedRemoteServerControlCommands < Test::Unit::TestCase
|
|
17
17
|
"total_commands_processed",
|
18
18
|
]
|
19
19
|
|
20
|
-
|
20
|
+
infos = r.info
|
21
21
|
|
22
|
-
|
22
|
+
infos.each do |info|
|
23
23
|
keys.each do |k|
|
24
24
|
msg = "expected #info to include #{k}"
|
25
25
|
assert info.keys.include?(k), msg
|
data/test/helper.rb
CHANGED
data/test/helper_test.rb
CHANGED
@@ -7,16 +7,18 @@ class TestHelper < Test::Unit::TestCase
|
|
7
7
|
include Helper
|
8
8
|
|
9
9
|
def test_version_comparison
|
10
|
-
v = Version.new("2.0.
|
10
|
+
v = Version.new("2.0.1")
|
11
11
|
|
12
|
-
assert v < "3"
|
13
12
|
assert v > "1"
|
14
13
|
assert v > "2"
|
14
|
+
assert v < "3"
|
15
|
+
assert v < "10"
|
15
16
|
|
16
17
|
assert v < "2.1"
|
17
|
-
assert v < "2.0.
|
18
|
-
assert v < "2.0.
|
18
|
+
assert v < "2.0.2"
|
19
|
+
assert v < "2.0.1.1"
|
20
|
+
assert v < "2.0.10"
|
19
21
|
|
20
|
-
assert v == "2.0.
|
22
|
+
assert v == "2.0.1"
|
21
23
|
end
|
22
24
|
end
|
data/test/internals_test.rb
CHANGED
@@ -280,7 +280,7 @@ class TestInternals < Test::Unit::TestCase
|
|
280
280
|
|
281
281
|
def test_connecting_to_unix_domain_socket
|
282
282
|
assert_nothing_raised do
|
283
|
-
Redis.new(OPTIONS.merge(:path => "/
|
283
|
+
Redis.new(OPTIONS.merge(:path => "./test/db/redis.sock")).ping
|
284
284
|
end
|
285
285
|
end
|
286
286
|
|
@@ -120,5 +120,31 @@ module Lint
|
|
120
120
|
assert_equal "1", r.brpoplpush("{zap}foo", "{zap}bar", 1)
|
121
121
|
end
|
122
122
|
end
|
123
|
+
|
124
|
+
driver(:ruby, :hiredis) do
|
125
|
+
def test_blpop_socket_timeout
|
126
|
+
mock(:delay => 1 + OPTIONS[:timeout] * 2) do |r|
|
127
|
+
assert_raises(Redis::TimeoutError) do
|
128
|
+
r.blpop("{zap}foo", :timeout => 1)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_brpop_socket_timeout
|
134
|
+
mock(:delay => 1 + OPTIONS[:timeout] * 2) do |r|
|
135
|
+
assert_raises(Redis::TimeoutError) do
|
136
|
+
r.brpop("{zap}foo", :timeout => 1)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_brpoplpush_socket_timeout
|
142
|
+
mock(:delay => 1 + OPTIONS[:timeout] * 2) do |r|
|
143
|
+
assert_raises(Redis::TimeoutError) do
|
144
|
+
r.brpoplpush("{zap}foo", "{zap}bar", :timeout => 1)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
123
149
|
end
|
124
150
|
end
|
data/test/lint/sets.rb
CHANGED
@@ -92,5 +92,34 @@ module Lint
|
|
92
92
|
|
93
93
|
assert_equal 2, r.scard("foo")
|
94
94
|
end
|
95
|
+
|
96
|
+
def test_srandmember_with_positive_count
|
97
|
+
r.sadd "foo", "s1"
|
98
|
+
r.sadd "foo", "s2"
|
99
|
+
r.sadd "foo", "s3"
|
100
|
+
r.sadd "foo", "s4"
|
101
|
+
|
102
|
+
4.times do
|
103
|
+
assert !(["s1", "s2", "s3", "s4"] & r.srandmember("foo", 3)).empty?
|
104
|
+
|
105
|
+
assert_equal 3, r.srandmember("foo", 3).size
|
106
|
+
end
|
107
|
+
|
108
|
+
assert_equal 4, r.scard("foo")
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_srandmember_with_negative_count
|
112
|
+
r.sadd "foo", "s1"
|
113
|
+
r.sadd "foo", "s2"
|
114
|
+
r.sadd "foo", "s3"
|
115
|
+
r.sadd "foo", "s4"
|
116
|
+
|
117
|
+
4.times do
|
118
|
+
assert !(["s1", "s2", "s3", "s4"] & r.srandmember("foo", -6)).empty?
|
119
|
+
assert_equal 6, r.srandmember("foo", -6).size
|
120
|
+
end
|
121
|
+
|
122
|
+
assert_equal 4, r.scard("foo")
|
123
|
+
end
|
95
124
|
end
|
96
125
|
end
|
data/test/lint/strings.rb
CHANGED
@@ -26,6 +26,14 @@ module Lint
|
|
26
26
|
assert_equal "1\n", r.get("foo")
|
27
27
|
end
|
28
28
|
|
29
|
+
def test_set_and_get_with_non_string_value
|
30
|
+
value = ["a", "b"]
|
31
|
+
|
32
|
+
r.set("foo", value)
|
33
|
+
|
34
|
+
assert_equal value.to_s, r.get("foo")
|
35
|
+
end
|
36
|
+
|
29
37
|
def test_set_and_get_with_ascii_characters
|
30
38
|
if defined?(Encoding)
|
31
39
|
with_external_encoding("ASCII-8BIT") do
|
@@ -45,6 +53,14 @@ module Lint
|
|
45
53
|
assert [0, 1].include? r.ttl("foo")
|
46
54
|
end
|
47
55
|
|
56
|
+
def test_setex_with_non_string_value
|
57
|
+
value = ["b", "a", "r"]
|
58
|
+
|
59
|
+
assert r.setex("foo", 1, value)
|
60
|
+
assert_equal value.to_s, r.get("foo")
|
61
|
+
assert [0, 1].include? r.ttl("foo")
|
62
|
+
end
|
63
|
+
|
48
64
|
def test_psetex
|
49
65
|
return if version < "2.5.4"
|
50
66
|
|
@@ -53,6 +69,16 @@ module Lint
|
|
53
69
|
assert [0, 1].include? r.ttl("foo")
|
54
70
|
end
|
55
71
|
|
72
|
+
def test_psetex_with_non_string_value
|
73
|
+
return if version < "2.5.4"
|
74
|
+
|
75
|
+
value = ["b", "a", "r"]
|
76
|
+
|
77
|
+
assert r.psetex("foo", 1000, value)
|
78
|
+
assert_equal value.to_s, r.get("foo")
|
79
|
+
assert [0, 1].include? r.ttl("foo")
|
80
|
+
end
|
81
|
+
|
56
82
|
def test_getset
|
57
83
|
r.set("foo", "bar")
|
58
84
|
|
@@ -60,14 +86,35 @@ module Lint
|
|
60
86
|
assert_equal "baz", r.get("foo")
|
61
87
|
end
|
62
88
|
|
89
|
+
def test_getset_with_non_string_value
|
90
|
+
r.set("foo", "zap")
|
91
|
+
|
92
|
+
value = ["b", "a", "r"]
|
93
|
+
|
94
|
+
assert_equal "zap", r.getset("foo", value)
|
95
|
+
assert_equal value.to_s, r.get("foo")
|
96
|
+
end
|
97
|
+
|
63
98
|
def test_setnx
|
64
|
-
r.set("foo", "
|
99
|
+
r.set("foo", "qux")
|
100
|
+
assert !r.setnx("foo", "bar")
|
101
|
+
assert_equal "qux", r.get("foo")
|
65
102
|
|
66
|
-
|
103
|
+
r.del("foo")
|
104
|
+
assert r.setnx("foo", "bar")
|
105
|
+
assert_equal "bar", r.get("foo")
|
106
|
+
end
|
67
107
|
|
68
|
-
|
108
|
+
def test_setnx_with_non_string_value
|
109
|
+
value = ["b", "a", "r"]
|
69
110
|
|
70
|
-
|
111
|
+
r.set("foo", "qux")
|
112
|
+
assert !r.setnx("foo", value)
|
113
|
+
assert_equal "qux", r.get("foo")
|
114
|
+
|
115
|
+
r.del("foo")
|
116
|
+
assert r.setnx("foo", value)
|
117
|
+
assert_equal value.to_s, r.get("foo")
|
71
118
|
end
|
72
119
|
|
73
120
|
def test_incr
|
@@ -133,6 +180,15 @@ module Lint
|
|
133
180
|
assert_equal "c", r.get("foo")
|
134
181
|
end
|
135
182
|
|
183
|
+
def test_bitcount
|
184
|
+
return if version < "2.5.10"
|
185
|
+
|
186
|
+
r.set("foo", "abcde")
|
187
|
+
|
188
|
+
assert_equal 10, r.bitcount("foo", 1, 3)
|
189
|
+
assert_equal 17, r.bitcount("foo", 0, -1)
|
190
|
+
end
|
191
|
+
|
136
192
|
def test_getrange
|
137
193
|
r.set("foo", "abcde")
|
138
194
|
|
@@ -148,6 +204,16 @@ module Lint
|
|
148
204
|
assert_equal "abare", r.get("foo")
|
149
205
|
end
|
150
206
|
|
207
|
+
def test_setrange_with_non_string_value
|
208
|
+
r.set("foo", "abcde")
|
209
|
+
|
210
|
+
value = ["b", "a", "r"]
|
211
|
+
|
212
|
+
r.setrange("foo", 2, value)
|
213
|
+
|
214
|
+
assert_equal "ab#{value.to_s}", r.get("foo")
|
215
|
+
end
|
216
|
+
|
151
217
|
def test_strlen
|
152
218
|
r.set "foo", "lorem"
|
153
219
|
|
data/test/lint/value_types.rb
CHANGED
@@ -80,6 +80,26 @@ module Lint
|
|
80
80
|
assert_in_range 1..2000, r.pttl("foo")
|
81
81
|
end
|
82
82
|
|
83
|
+
def test_dump_and_restore
|
84
|
+
return if version < "2.5.7"
|
85
|
+
|
86
|
+
r.set("foo", "a")
|
87
|
+
v = r.dump("foo")
|
88
|
+
r.del("foo")
|
89
|
+
|
90
|
+
assert r.restore("foo", 1000, v)
|
91
|
+
assert_equal "a", r.get("foo")
|
92
|
+
assert [0, 1].include? r.ttl("foo")
|
93
|
+
|
94
|
+
r.rpush("bar", ["b", "c", "d"])
|
95
|
+
w = r.dump("bar")
|
96
|
+
r.del("bar")
|
97
|
+
|
98
|
+
assert r.restore("bar", 1000, w)
|
99
|
+
assert_equal ["b", "c", "d"], r.lrange("bar", 0, -1)
|
100
|
+
assert [0, 1].include? r.ttl("bar")
|
101
|
+
end
|
102
|
+
|
83
103
|
def test_move
|
84
104
|
r.select 14
|
85
105
|
r.flushdb
|
data/test/test.conf
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -17,7 +17,7 @@ authors:
|
|
17
17
|
autorequire:
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
|
-
date:
|
20
|
+
date: 2013-03-01 00:00:00.000000000 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: rake
|