redis 3.0.0.rc1 → 3.0.0.rc2
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/.travis.yml +50 -0
- data/.travis/Gemfile +11 -0
- data/CHANGELOG.md +47 -19
- data/README.md +160 -149
- data/Rakefile +15 -50
- data/examples/pubsub.rb +1 -1
- data/examples/unicorn/config.ru +1 -1
- data/examples/unicorn/unicorn.rb +1 -1
- data/lib/redis.rb +790 -390
- data/lib/redis/client.rb +137 -49
- data/lib/redis/connection/hiredis.rb +26 -15
- data/lib/redis/connection/ruby.rb +170 -53
- data/lib/redis/connection/synchrony.rb +23 -35
- data/lib/redis/distributed.rb +92 -32
- data/lib/redis/errors.rb +4 -2
- data/lib/redis/pipeline.rb +17 -6
- data/lib/redis/version.rb +1 -1
- data/redis.gemspec +4 -6
- data/test/blocking_commands_test.rb +42 -0
- data/test/command_map_test.rb +18 -17
- data/test/commands_on_hashes_test.rb +13 -12
- data/test/commands_on_lists_test.rb +35 -45
- data/test/commands_on_sets_test.rb +55 -54
- data/test/commands_on_sorted_sets_test.rb +106 -105
- data/test/commands_on_strings_test.rb +64 -55
- data/test/commands_on_value_types_test.rb +66 -54
- data/test/connection_handling_test.rb +136 -151
- data/test/distributed_blocking_commands_test.rb +33 -40
- data/test/distributed_commands_on_hashes_test.rb +6 -7
- data/test/distributed_commands_on_lists_test.rb +13 -14
- data/test/distributed_commands_on_sets_test.rb +57 -58
- data/test/distributed_commands_on_sorted_sets_test.rb +11 -12
- data/test/distributed_commands_on_strings_test.rb +31 -32
- data/test/distributed_commands_on_value_types_test.rb +61 -46
- data/test/distributed_commands_requiring_clustering_test.rb +108 -108
- data/test/distributed_connection_handling_test.rb +14 -15
- data/test/distributed_internals_test.rb +7 -19
- data/test/distributed_key_tags_test.rb +36 -36
- data/test/distributed_persistence_control_commands_test.rb +17 -14
- data/test/distributed_publish_subscribe_test.rb +61 -69
- data/test/distributed_remote_server_control_commands_test.rb +39 -28
- data/test/distributed_sorting_test.rb +12 -13
- data/test/distributed_test.rb +40 -41
- data/test/distributed_transactions_test.rb +20 -21
- data/test/encoding_test.rb +12 -9
- data/test/error_replies_test.rb +42 -36
- data/test/helper.rb +118 -85
- data/test/helper_test.rb +20 -6
- data/test/internals_test.rb +167 -103
- data/test/lint/blocking_commands.rb +124 -0
- data/test/lint/hashes.rb +115 -93
- data/test/lint/lists.rb +86 -80
- data/test/lint/sets.rb +68 -62
- data/test/lint/sorted_sets.rb +200 -195
- data/test/lint/strings.rb +112 -94
- data/test/lint/value_types.rb +76 -55
- data/test/persistence_control_commands_test.rb +17 -12
- data/test/pipelining_commands_test.rb +135 -126
- data/test/publish_subscribe_test.rb +105 -110
- data/test/remote_server_control_commands_test.rb +74 -58
- data/test/sorting_test.rb +31 -29
- data/test/support/connection/hiredis.rb +1 -0
- data/test/support/connection/ruby.rb +1 -0
- data/test/support/connection/synchrony.rb +17 -0
- data/test/{redis_mock.rb → support/redis_mock.rb} +24 -21
- data/test/support/wire/synchrony.rb +24 -0
- data/test/support/wire/thread.rb +5 -0
- data/test/synchrony_driver.rb +9 -9
- data/test/test.conf +1 -1
- data/test/thread_safety_test.rb +21 -19
- data/test/transactions_test.rb +189 -118
- data/test/unknown_commands_test.rb +9 -8
- data/test/url_param_test.rb +46 -41
- metadata +28 -43
- data/TODO.md +0 -4
- data/benchmarking/thread_safety.rb +0 -38
- data/test/lint/internals.rb +0 -36
@@ -1,100 +1,92 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require "redis/distributed"
|
3
|
+
require "helper"
|
5
4
|
|
6
|
-
|
7
|
-
log = StringIO.new
|
8
|
-
init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
|
9
|
-
end
|
5
|
+
class TestDistributedPublishSubscribe < Test::Unit::TestCase
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
include Helper::Distributed
|
8
|
+
|
9
|
+
def test_subscribe_and_unsubscribe
|
10
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
11
|
+
r.subscribe("foo", "bar") { }
|
12
|
+
end
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
15
|
+
r.subscribe("{qux}foo", "bar") { }
|
16
|
+
end
|
18
17
|
end
|
19
|
-
end
|
20
18
|
|
21
|
-
|
22
|
-
|
19
|
+
def test_subscribe_and_unsubscribe_with_tags
|
20
|
+
@subscribed = false
|
21
|
+
@unsubscribed = false
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
wire = Wire.new do
|
24
|
+
r.subscribe("foo") do |on|
|
25
|
+
on.subscribe do |channel, total|
|
26
|
+
@subscribed = true
|
27
|
+
@t1 = total
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
on.message do |channel, message|
|
31
|
+
if message == "s1"
|
32
|
+
r.unsubscribe
|
33
|
+
@message = message
|
34
|
+
end
|
35
35
|
end
|
36
|
-
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
on.unsubscribe do |channel, total|
|
38
|
+
@unsubscribed = true
|
39
|
+
@t2 = total
|
40
|
+
end
|
41
41
|
end
|
42
|
-
|
43
|
-
listening = true
|
44
42
|
end
|
45
|
-
end
|
46
43
|
|
47
|
-
|
44
|
+
# Wait until the subscription is active before publishing
|
45
|
+
Wire.pass while !@subscribed
|
48
46
|
|
49
|
-
|
47
|
+
Redis::Distributed.new(NODES).publish("foo", "s1")
|
50
48
|
|
51
|
-
|
49
|
+
wire.join
|
52
50
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
51
|
+
assert @subscribed
|
52
|
+
assert_equal 1, @t1
|
53
|
+
assert @unsubscribed
|
54
|
+
assert_equal 0, @t2
|
55
|
+
assert_equal "s1", @message
|
56
|
+
end
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
@channels = []
|
58
|
+
def test_subscribe_within_subscribe
|
59
|
+
@channels = []
|
63
60
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
wire = Wire.new do
|
62
|
+
r.subscribe("foo") do |on|
|
63
|
+
on.subscribe do |channel, total|
|
64
|
+
@channels << channel
|
68
65
|
|
69
|
-
|
70
|
-
|
66
|
+
r.subscribe("bar") if channel == "foo"
|
67
|
+
r.unsubscribe if channel == "bar"
|
68
|
+
end
|
71
69
|
end
|
72
|
-
|
73
|
-
listening = true
|
74
70
|
end
|
75
|
-
end
|
76
|
-
|
77
|
-
Wire.pass while !listening
|
78
71
|
|
79
|
-
|
72
|
+
wire.join
|
80
73
|
|
81
|
-
|
82
|
-
|
83
|
-
assert ["foo", "bar"] == @channels
|
84
|
-
end
|
74
|
+
assert_equal ["foo", "bar"], @channels
|
75
|
+
end
|
85
76
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
77
|
+
def test_other_commands_within_a_subscribe
|
78
|
+
assert_raise Redis::CommandError do
|
79
|
+
r.subscribe("foo") do |on|
|
80
|
+
on.subscribe do |channel, total|
|
81
|
+
r.set("bar", "s2")
|
82
|
+
end
|
91
83
|
end
|
92
84
|
end
|
93
85
|
end
|
94
|
-
end
|
95
86
|
|
96
|
-
|
97
|
-
|
98
|
-
|
87
|
+
def test_subscribe_without_a_block
|
88
|
+
assert_raise LocalJumpError do
|
89
|
+
r.subscribe("foo")
|
90
|
+
end
|
99
91
|
end
|
100
92
|
end
|
@@ -1,42 +1,53 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require "redis/distributed"
|
3
|
+
require "helper"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
class TestDistributedRemoteServerControlCommands < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include Helper::Distributed
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
def test_info
|
10
|
+
%w(last_save_time redis_version total_connections_received connected_clients total_commands_processed connected_slaves uptime_in_seconds used_memory uptime_in_days changes_since_last_save).each do |x|
|
11
|
+
r.info.each do |info|
|
12
|
+
assert info.keys.include?(x)
|
13
|
+
end
|
15
14
|
end
|
16
15
|
end
|
17
|
-
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
next if version(r) < 209000
|
17
|
+
def test_info_commandstats
|
18
|
+
return if version < "2.9.0"
|
22
19
|
|
23
|
-
|
24
|
-
|
20
|
+
r.nodes.each { |n| n.config(:resetstat) }
|
21
|
+
r.ping # Executed on every node
|
25
22
|
|
26
|
-
|
27
|
-
|
23
|
+
r.info(:commandstats).each do |info|
|
24
|
+
assert_equal "1", info["ping"]["calls"]
|
25
|
+
end
|
28
26
|
end
|
29
|
-
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
def test_monitor
|
29
|
+
begin
|
30
|
+
r.monitor
|
31
|
+
rescue Exception => ex
|
32
|
+
ensure
|
33
|
+
assert ex.kind_of?(NotImplementedError)
|
34
|
+
end
|
37
35
|
end
|
38
|
-
end
|
39
36
|
|
40
|
-
|
41
|
-
|
37
|
+
def test_echo
|
38
|
+
assert_equal ["foo bar baz\n"], r.echo("foo bar baz\n")
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_time
|
42
|
+
return if version < "2.5.4"
|
43
|
+
|
44
|
+
# Test that the difference between the time that Ruby reports and the time
|
45
|
+
# that Redis reports is minimal (prevents the test from being racy).
|
46
|
+
r.time.each do |rv|
|
47
|
+
redis_usec = rv[0] * 1_000_000 + rv[1]
|
48
|
+
ruby_usec = Integer(Time.now.to_f * 1_000_000)
|
49
|
+
|
50
|
+
assert 500_000 > (ruby_usec - redis_usec).abs
|
51
|
+
end
|
52
|
+
end
|
42
53
|
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require "redis/distributed"
|
3
|
+
require "helper"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
class TestDistributedSorting < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include Helper::Distributed
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
def test_sort
|
10
|
+
assert_raise(Redis::Distributed::CannotDistribute) do
|
11
|
+
r.set("foo:1", "s1")
|
12
|
+
r.set("foo:2", "s2")
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
r.rpush("bar", "1")
|
15
|
+
r.rpush("bar", "2")
|
18
16
|
|
19
|
-
|
17
|
+
r.sort("bar", :get => "foo:*", :limit => [0, 1])
|
18
|
+
end
|
20
19
|
end
|
21
20
|
end
|
data/test/distributed_test.rb
CHANGED
@@ -1,59 +1,58 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require "redis/distributed"
|
3
|
+
require "helper"
|
5
4
|
|
6
|
-
|
7
|
-
log = StringIO.new
|
8
|
-
init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
|
9
|
-
end
|
5
|
+
class TestDistributed < Test::Unit::TestCase
|
10
6
|
|
11
|
-
|
12
|
-
@r = Redis::Distributed.new ["redis://localhost:6379/15", *NODES]
|
7
|
+
include Helper::Distributed
|
13
8
|
|
14
|
-
|
15
|
-
@r.
|
16
|
-
end
|
9
|
+
def test_handle_multiple_servers
|
10
|
+
@r = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
100.times do |idx|
|
13
|
+
@r.set(idx.to_s, "foo#{idx}")
|
14
|
+
end
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
16
|
+
100.times do |idx|
|
17
|
+
assert_equal "foo#{idx}", @r.get(idx.to_s)
|
18
|
+
end
|
25
19
|
|
26
|
-
|
27
|
-
|
20
|
+
assert_equal "0", @r.keys("*").sort.first
|
21
|
+
assert_equal "string", @r.type("1")
|
22
|
+
end
|
28
23
|
|
29
|
-
|
24
|
+
def test_add_nodes
|
25
|
+
logger = Logger.new("/dev/null")
|
30
26
|
|
31
|
-
|
32
|
-
assert 6379 == @r.nodes[0].client.port
|
33
|
-
assert 15 == @r.nodes[0].client.db
|
34
|
-
assert 10 == @r.nodes[0].client.timeout
|
35
|
-
assert logger == @r.nodes[0].client.logger
|
27
|
+
@r = Redis::Distributed.new NODES, :logger => logger, :timeout => 10
|
36
28
|
|
37
|
-
|
29
|
+
assert_equal "127.0.0.1", @r.nodes[0].client.host
|
30
|
+
assert_equal PORT, @r.nodes[0].client.port
|
31
|
+
assert_equal 15, @r.nodes[0].client.db
|
32
|
+
assert_equal 10, @r.nodes[0].client.timeout
|
33
|
+
assert_equal logger, @r.nodes[0].client.logger
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
35
|
+
@r.add_node("redis://localhost:6380/14")
|
36
|
+
|
37
|
+
assert_equal "localhost", @r.nodes[1].client.host
|
38
|
+
assert_equal 6380, @r.nodes[1].client.port
|
39
|
+
assert_equal 14, @r.nodes[1].client.db
|
40
|
+
assert_equal 10, @r.nodes[1].client.timeout
|
41
|
+
assert_equal logger, @r.nodes[1].client.logger
|
42
|
+
end
|
45
43
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
def test_pipelining_commands_cannot_be_distributed
|
45
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
46
|
+
r.pipelined do
|
47
|
+
r.lpush "foo", "s1"
|
48
|
+
r.lpush "foo", "s2"
|
49
|
+
end
|
51
50
|
end
|
52
51
|
end
|
53
|
-
end
|
54
52
|
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
def test_unknown_commands_does_not_work_by_default
|
54
|
+
assert_raise NoMethodError do
|
55
|
+
r.not_yet_implemented_command
|
56
|
+
end
|
58
57
|
end
|
59
58
|
end
|
@@ -1,33 +1,32 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require "redis/distributed"
|
3
|
+
require "helper"
|
5
4
|
|
6
|
-
|
7
|
-
log = StringIO.new
|
8
|
-
init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
|
9
|
-
end
|
5
|
+
class TestDistributedTransactions < Test::Unit::TestCase
|
10
6
|
|
11
|
-
|
12
|
-
@foo = nil
|
7
|
+
include Helper::Distributed
|
13
8
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
9
|
+
def test_multi_discard
|
10
|
+
@foo = nil
|
17
11
|
|
18
|
-
|
12
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
13
|
+
r.multi { @foo = 1 }
|
14
|
+
end
|
19
15
|
|
20
|
-
|
21
|
-
r.discard
|
22
|
-
end
|
23
|
-
end
|
16
|
+
assert_equal nil, @foo
|
24
17
|
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
19
|
+
r.discard
|
20
|
+
end
|
28
21
|
end
|
29
22
|
|
30
|
-
|
31
|
-
|
23
|
+
def test_watch_unwatch
|
24
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
25
|
+
r.watch("foo")
|
26
|
+
end
|
27
|
+
|
28
|
+
assert_raise Redis::Distributed::CannotDistribute do
|
29
|
+
r.unwatch
|
30
|
+
end
|
32
31
|
end
|
33
32
|
end
|
data/test/encoding_test.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
3
|
+
require "helper"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
class TestEncoding < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include Helper::Client
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def test_returns_properly_encoded_strings
|
10
|
+
if defined?(Encoding)
|
11
|
+
with_external_encoding("UTF-8") do
|
12
|
+
r.set "foo", "שלום"
|
12
13
|
|
13
|
-
|
14
|
+
assert_equal "Shalom שלום", "Shalom " + r.get("foo")
|
15
|
+
end
|
16
|
+
end
|
14
17
|
end
|
15
|
-
end
|
18
|
+
end
|