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.
Files changed (77) hide show
  1. data/.travis.yml +50 -0
  2. data/.travis/Gemfile +11 -0
  3. data/CHANGELOG.md +47 -19
  4. data/README.md +160 -149
  5. data/Rakefile +15 -50
  6. data/examples/pubsub.rb +1 -1
  7. data/examples/unicorn/config.ru +1 -1
  8. data/examples/unicorn/unicorn.rb +1 -1
  9. data/lib/redis.rb +790 -390
  10. data/lib/redis/client.rb +137 -49
  11. data/lib/redis/connection/hiredis.rb +26 -15
  12. data/lib/redis/connection/ruby.rb +170 -53
  13. data/lib/redis/connection/synchrony.rb +23 -35
  14. data/lib/redis/distributed.rb +92 -32
  15. data/lib/redis/errors.rb +4 -2
  16. data/lib/redis/pipeline.rb +17 -6
  17. data/lib/redis/version.rb +1 -1
  18. data/redis.gemspec +4 -6
  19. data/test/blocking_commands_test.rb +42 -0
  20. data/test/command_map_test.rb +18 -17
  21. data/test/commands_on_hashes_test.rb +13 -12
  22. data/test/commands_on_lists_test.rb +35 -45
  23. data/test/commands_on_sets_test.rb +55 -54
  24. data/test/commands_on_sorted_sets_test.rb +106 -105
  25. data/test/commands_on_strings_test.rb +64 -55
  26. data/test/commands_on_value_types_test.rb +66 -54
  27. data/test/connection_handling_test.rb +136 -151
  28. data/test/distributed_blocking_commands_test.rb +33 -40
  29. data/test/distributed_commands_on_hashes_test.rb +6 -7
  30. data/test/distributed_commands_on_lists_test.rb +13 -14
  31. data/test/distributed_commands_on_sets_test.rb +57 -58
  32. data/test/distributed_commands_on_sorted_sets_test.rb +11 -12
  33. data/test/distributed_commands_on_strings_test.rb +31 -32
  34. data/test/distributed_commands_on_value_types_test.rb +61 -46
  35. data/test/distributed_commands_requiring_clustering_test.rb +108 -108
  36. data/test/distributed_connection_handling_test.rb +14 -15
  37. data/test/distributed_internals_test.rb +7 -19
  38. data/test/distributed_key_tags_test.rb +36 -36
  39. data/test/distributed_persistence_control_commands_test.rb +17 -14
  40. data/test/distributed_publish_subscribe_test.rb +61 -69
  41. data/test/distributed_remote_server_control_commands_test.rb +39 -28
  42. data/test/distributed_sorting_test.rb +12 -13
  43. data/test/distributed_test.rb +40 -41
  44. data/test/distributed_transactions_test.rb +20 -21
  45. data/test/encoding_test.rb +12 -9
  46. data/test/error_replies_test.rb +42 -36
  47. data/test/helper.rb +118 -85
  48. data/test/helper_test.rb +20 -6
  49. data/test/internals_test.rb +167 -103
  50. data/test/lint/blocking_commands.rb +124 -0
  51. data/test/lint/hashes.rb +115 -93
  52. data/test/lint/lists.rb +86 -80
  53. data/test/lint/sets.rb +68 -62
  54. data/test/lint/sorted_sets.rb +200 -195
  55. data/test/lint/strings.rb +112 -94
  56. data/test/lint/value_types.rb +76 -55
  57. data/test/persistence_control_commands_test.rb +17 -12
  58. data/test/pipelining_commands_test.rb +135 -126
  59. data/test/publish_subscribe_test.rb +105 -110
  60. data/test/remote_server_control_commands_test.rb +74 -58
  61. data/test/sorting_test.rb +31 -29
  62. data/test/support/connection/hiredis.rb +1 -0
  63. data/test/support/connection/ruby.rb +1 -0
  64. data/test/support/connection/synchrony.rb +17 -0
  65. data/test/{redis_mock.rb → support/redis_mock.rb} +24 -21
  66. data/test/support/wire/synchrony.rb +24 -0
  67. data/test/support/wire/thread.rb +5 -0
  68. data/test/synchrony_driver.rb +9 -9
  69. data/test/test.conf +1 -1
  70. data/test/thread_safety_test.rb +21 -19
  71. data/test/transactions_test.rb +189 -118
  72. data/test/unknown_commands_test.rb +9 -8
  73. data/test/url_param_test.rb +46 -41
  74. metadata +28 -43
  75. data/TODO.md +0 -4
  76. data/benchmarking/thread_safety.rb +0 -38
  77. data/test/lint/internals.rb +0 -36
@@ -1,148 +1,148 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
- require "redis/distributed"
3
+ require "helper"
5
4
 
6
- setup do
7
- log = StringIO.new
8
- init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
- end
5
+ class TestDistributedCommandsRequiringClustering < Test::Unit::TestCase
10
6
 
11
- test "RENAME" do |r|
12
- r.set("{qux}foo", "s1")
13
- r.rename "{qux}foo", "{qux}bar"
7
+ include Helper::Distributed
14
8
 
15
- assert "s1" == r.get("{qux}bar")
16
- assert nil == r.get("{qux}foo")
17
- end
9
+ def test_rename
10
+ r.set("{qux}foo", "s1")
11
+ r.rename "{qux}foo", "{qux}bar"
18
12
 
19
- test "RENAMENX" do |r|
20
- r.set("{qux}foo", "s1")
21
- r.set("{qux}bar", "s2")
13
+ assert_equal "s1", r.get("{qux}bar")
14
+ assert_equal nil, r.get("{qux}foo")
15
+ end
22
16
 
23
- assert false == r.renamenx("{qux}foo", "{qux}bar")
17
+ def test_renamenx
18
+ r.set("{qux}foo", "s1")
19
+ r.set("{qux}bar", "s2")
24
20
 
25
- assert "s1" == r.get("{qux}foo")
26
- assert "s2" == r.get("{qux}bar")
27
- end
21
+ assert_equal false, r.renamenx("{qux}foo", "{qux}bar")
28
22
 
29
- test "BRPOPLPUSH" do |r|
30
- r.rpush "{qux}foo", "s1"
31
- r.rpush "{qux}foo", "s2"
23
+ assert_equal "s1", r.get("{qux}foo")
24
+ assert_equal "s2", r.get("{qux}bar")
25
+ end
32
26
 
33
- assert_equal "s2", r.brpoplpush("{qux}foo", "{qux}bar", 1)
34
- assert_equal ["s2"], r.lrange("{qux}bar", 0, -1)
35
- end
27
+ def test_brpoplpush
28
+ r.rpush "{qux}foo", "s1"
29
+ r.rpush "{qux}foo", "s2"
36
30
 
37
- test "RPOPLPUSH" do |r|
38
- r.rpush "{qux}foo", "s1"
39
- r.rpush "{qux}foo", "s2"
31
+ assert_equal "s2", r.brpoplpush("{qux}foo", "{qux}bar", :timeout => 1)
32
+ assert_equal ["s2"], r.lrange("{qux}bar", 0, -1)
33
+ end
40
34
 
41
- assert "s2" == r.rpoplpush("{qux}foo", "{qux}bar")
42
- assert ["s2"] == r.lrange("{qux}bar", 0, -1)
43
- assert "s1" == r.rpoplpush("{qux}foo", "{qux}bar")
44
- assert ["s1", "s2"] == r.lrange("{qux}bar", 0, -1)
45
- end
35
+ def test_rpoplpush
36
+ r.rpush "{qux}foo", "s1"
37
+ r.rpush "{qux}foo", "s2"
46
38
 
47
- test "SMOVE" do |r|
48
- r.sadd "{qux}foo", "s1"
49
- r.sadd "{qux}bar", "s2"
39
+ assert_equal "s2", r.rpoplpush("{qux}foo", "{qux}bar")
40
+ assert_equal ["s2"], r.lrange("{qux}bar", 0, -1)
41
+ assert_equal "s1", r.rpoplpush("{qux}foo", "{qux}bar")
42
+ assert_equal ["s1", "s2"], r.lrange("{qux}bar", 0, -1)
43
+ end
50
44
 
51
- assert r.smove("{qux}foo", "{qux}bar", "s1")
52
- assert r.sismember("{qux}bar", "s1")
53
- end
45
+ def test_smove
46
+ r.sadd "{qux}foo", "s1"
47
+ r.sadd "{qux}bar", "s2"
54
48
 
55
- test "SINTER" do |r|
56
- r.sadd "{qux}foo", "s1"
57
- r.sadd "{qux}foo", "s2"
58
- r.sadd "{qux}bar", "s2"
49
+ assert r.smove("{qux}foo", "{qux}bar", "s1")
50
+ assert r.sismember("{qux}bar", "s1")
51
+ end
59
52
 
60
- assert ["s2"] == r.sinter("{qux}foo", "{qux}bar")
61
- end
53
+ def test_sinter
54
+ r.sadd "{qux}foo", "s1"
55
+ r.sadd "{qux}foo", "s2"
56
+ r.sadd "{qux}bar", "s2"
62
57
 
63
- test "SINTERSTORE" do |r|
64
- r.sadd "{qux}foo", "s1"
65
- r.sadd "{qux}foo", "s2"
66
- r.sadd "{qux}bar", "s2"
58
+ assert_equal ["s2"], r.sinter("{qux}foo", "{qux}bar")
59
+ end
67
60
 
68
- r.sinterstore("{qux}baz", "{qux}foo", "{qux}bar")
61
+ def test_sinterstore
62
+ r.sadd "{qux}foo", "s1"
63
+ r.sadd "{qux}foo", "s2"
64
+ r.sadd "{qux}bar", "s2"
69
65
 
70
- assert ["s2"] == r.smembers("{qux}baz")
71
- end
66
+ r.sinterstore("{qux}baz", "{qux}foo", "{qux}bar")
72
67
 
73
- test "SUNION" do |r|
74
- r.sadd "{qux}foo", "s1"
75
- r.sadd "{qux}foo", "s2"
76
- r.sadd "{qux}bar", "s2"
77
- r.sadd "{qux}bar", "s3"
68
+ assert_equal ["s2"], r.smembers("{qux}baz")
69
+ end
78
70
 
79
- assert ["s1", "s2", "s3"] == r.sunion("{qux}foo", "{qux}bar").sort
80
- end
71
+ def test_sunion
72
+ r.sadd "{qux}foo", "s1"
73
+ r.sadd "{qux}foo", "s2"
74
+ r.sadd "{qux}bar", "s2"
75
+ r.sadd "{qux}bar", "s3"
81
76
 
82
- test "SUNIONSTORE" do |r|
83
- r.sadd "{qux}foo", "s1"
84
- r.sadd "{qux}foo", "s2"
85
- r.sadd "{qux}bar", "s2"
86
- r.sadd "{qux}bar", "s3"
77
+ assert_equal ["s1", "s2", "s3"], r.sunion("{qux}foo", "{qux}bar").sort
78
+ end
87
79
 
88
- r.sunionstore("{qux}baz", "{qux}foo", "{qux}bar")
80
+ def test_sunionstore
81
+ r.sadd "{qux}foo", "s1"
82
+ r.sadd "{qux}foo", "s2"
83
+ r.sadd "{qux}bar", "s2"
84
+ r.sadd "{qux}bar", "s3"
89
85
 
90
- assert ["s1", "s2", "s3"] == r.smembers("{qux}baz").sort
91
- end
86
+ r.sunionstore("{qux}baz", "{qux}foo", "{qux}bar")
92
87
 
93
- test "SDIFF" do |r|
94
- r.sadd "{qux}foo", "s1"
95
- r.sadd "{qux}foo", "s2"
96
- r.sadd "{qux}bar", "s2"
97
- r.sadd "{qux}bar", "s3"
88
+ assert_equal ["s1", "s2", "s3"], r.smembers("{qux}baz").sort
89
+ end
98
90
 
99
- assert ["s1"] == r.sdiff("{qux}foo", "{qux}bar")
100
- assert ["s3"] == r.sdiff("{qux}bar", "{qux}foo")
101
- end
91
+ def test_sdiff
92
+ r.sadd "{qux}foo", "s1"
93
+ r.sadd "{qux}foo", "s2"
94
+ r.sadd "{qux}bar", "s2"
95
+ r.sadd "{qux}bar", "s3"
102
96
 
103
- test "SDIFFSTORE" do |r|
104
- r.sadd "{qux}foo", "s1"
105
- r.sadd "{qux}foo", "s2"
106
- r.sadd "{qux}bar", "s2"
107
- r.sadd "{qux}bar", "s3"
97
+ assert_equal ["s1"], r.sdiff("{qux}foo", "{qux}bar")
98
+ assert_equal ["s3"], r.sdiff("{qux}bar", "{qux}foo")
99
+ end
108
100
 
109
- r.sdiffstore("{qux}baz", "{qux}foo", "{qux}bar")
101
+ def test_sdiffstore
102
+ r.sadd "{qux}foo", "s1"
103
+ r.sadd "{qux}foo", "s2"
104
+ r.sadd "{qux}bar", "s2"
105
+ r.sadd "{qux}bar", "s3"
110
106
 
111
- assert ["s1"] == r.smembers("{qux}baz")
112
- end
107
+ r.sdiffstore("{qux}baz", "{qux}foo", "{qux}bar")
113
108
 
114
- test "SORT" do |r|
115
- r.set("{qux}foo:1", "s1")
116
- r.set("{qux}foo:2", "s2")
109
+ assert_equal ["s1"], r.smembers("{qux}baz")
110
+ end
117
111
 
118
- r.rpush("{qux}bar", "1")
119
- r.rpush("{qux}bar", "2")
112
+ def test_sort
113
+ r.set("{qux}foo:1", "s1")
114
+ r.set("{qux}foo:2", "s2")
120
115
 
121
- assert ["s1"] == r.sort("{qux}bar", :get => "{qux}foo:*", :limit => [0, 1])
122
- assert ["s2"] == r.sort("{qux}bar", :get => "{qux}foo:*", :limit => [0, 1], :order => "desc alpha")
123
- end
116
+ r.rpush("{qux}bar", "1")
117
+ r.rpush("{qux}bar", "2")
124
118
 
125
- test "SORT with an array of GETs" do |r|
126
- r.set("{qux}foo:1:a", "s1a")
127
- r.set("{qux}foo:1:b", "s1b")
119
+ assert_equal ["s1"], r.sort("{qux}bar", :get => "{qux}foo:*", :limit => [0, 1])
120
+ assert_equal ["s2"], r.sort("{qux}bar", :get => "{qux}foo:*", :limit => [0, 1], :order => "desc alpha")
121
+ end
128
122
 
129
- r.set("{qux}foo:2:a", "s2a")
130
- r.set("{qux}foo:2:b", "s2b")
123
+ def test_sort_with_an_array_of_gets
124
+ r.set("{qux}foo:1:a", "s1a")
125
+ r.set("{qux}foo:1:b", "s1b")
131
126
 
132
- r.rpush("{qux}bar", "1")
133
- r.rpush("{qux}bar", "2")
127
+ r.set("{qux}foo:2:a", "s2a")
128
+ r.set("{qux}foo:2:b", "s2b")
134
129
 
135
- assert ["s1a", "s1b"] == r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"], :limit => [0, 1])
136
- assert ["s2a", "s2b"] == r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"], :limit => [0, 1], :order => "desc alpha")
137
- end
130
+ r.rpush("{qux}bar", "1")
131
+ r.rpush("{qux}bar", "2")
132
+
133
+ assert_equal [["s1a", "s1b"]], r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"], :limit => [0, 1])
134
+ assert_equal [["s2a", "s2b"]], r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"], :limit => [0, 1], :order => "desc alpha")
135
+ assert_equal [["s1a", "s1b"], ["s2a", "s2b"]], r.sort("{qux}bar", :get => ["{qux}foo:*:a", "{qux}foo:*:b"])
136
+ end
138
137
 
139
- test "SORT with STORE" do |r|
140
- r.set("{qux}foo:1", "s1")
141
- r.set("{qux}foo:2", "s2")
138
+ def test_sort_with_store
139
+ r.set("{qux}foo:1", "s1")
140
+ r.set("{qux}foo:2", "s2")
142
141
 
143
- r.rpush("{qux}bar", "1")
144
- r.rpush("{qux}bar", "2")
142
+ r.rpush("{qux}bar", "1")
143
+ r.rpush("{qux}bar", "2")
145
144
 
146
- r.sort("{qux}bar", :get => "{qux}foo:*", :store => "{qux}baz")
147
- assert ["s1", "s2"] == r.lrange("{qux}baz", 0, -1)
145
+ r.sort("{qux}bar", :get => "{qux}foo:*", :store => "{qux}baz")
146
+ assert_equal ["s1", "s2"], r.lrange("{qux}baz", 0, -1)
147
+ end
148
148
  end
@@ -1,24 +1,23 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
- require "redis/distributed"
3
+ require "helper"
5
4
 
6
- setup do
7
- log = StringIO.new
8
- init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
- end
5
+ class TestDistributedConnectionHandling < Test::Unit::TestCase
10
6
 
11
- test "PING" do |r|
12
- assert ["PONG"] == r.ping
13
- end
7
+ include Helper::Distributed
8
+
9
+ def test_ping
10
+ assert_equal ["PONG"], r.ping
11
+ end
14
12
 
15
- test "SELECT" do |r|
16
- r.set "foo", "bar"
13
+ def test_select
14
+ r.set "foo", "bar"
17
15
 
18
- r.select 14
19
- assert nil == r.get("foo")
16
+ r.select 14
17
+ assert_equal nil, r.get("foo")
20
18
 
21
- r.select 15
19
+ r.select 15
22
20
 
23
- assert "bar" == r.get("foo")
21
+ assert_equal "bar", r.get("foo")
22
+ end
24
23
  end
@@ -1,27 +1,15 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
- require File.expand_path("./redis_mock", File.dirname(__FILE__))
3
+ require "helper"
5
4
 
6
- include RedisMock::Helper
5
+ class TestDistributedInternals < Test::Unit::TestCase
7
6
 
8
- require "redis/distributed"
7
+ include Helper::Distributed
9
8
 
10
- setup do
11
- log = StringIO.new
12
- [init(Redis::Distributed.new(NODES, :logger => ::Logger.new(log))), log]
13
- end
14
-
15
- $TEST_PIPELINING = false
16
-
17
- load File.expand_path("./lint/internals.rb", File.dirname(__FILE__))
18
-
19
- test "provides a meaningful inspect" do |r, _|
20
- nodes = ["redis://localhost:6379/15", *NODES]
21
- @r = Redis::Distributed.new nodes
9
+ def test_provides_a_meaningful_inspect
10
+ nodes = ["redis://localhost:#{PORT}/15", *NODES]
11
+ redis = Redis::Distributed.new nodes
22
12
 
23
- node_info = nodes.map do |node|
24
- "#{node} (Redis v#{@r.info.first["redis_version"]})"
13
+ assert_equal "#<Redis client v#{Redis::VERSION} for #{redis.nodes.map(&:id).join(', ')}>", redis.inspect
25
14
  end
26
- assert "#<Redis client v#{Redis::VERSION} connected to #{node_info.join(', ')}>" == @r.inspect
27
15
  end
@@ -1,52 +1,52 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
- require "redis/distributed"
3
+ require "helper"
5
4
 
6
- setup do
7
- log = StringIO.new
8
- init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
- end
10
-
11
- test "hashes consistently" do
12
- r1 = Redis::Distributed.new ["redis://localhost:6379/15", *NODES]
13
- r2 = Redis::Distributed.new ["redis://localhost:6379/15", *NODES]
14
- r3 = Redis::Distributed.new ["redis://localhost:6379/15", *NODES]
5
+ class TestDistributedKeyTags < Test::Unit::TestCase
15
6
 
16
- assert r1.node_for("foo").id == r2.node_for("foo").id
17
- assert r1.node_for("foo").id == r3.node_for("foo").id
18
- end
7
+ include Helper
8
+ include Helper::Distributed
19
9
 
20
- test "allows clustering of keys" do |r|
21
- r = Redis::Distributed.new(NODES)
22
- r.add_node("redis://localhost:6379/14")
23
- r.flushdb
10
+ def test_hashes_consistently
11
+ r1 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
12
+ r2 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
13
+ r3 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
24
14
 
25
- 100.times do |i|
26
- r.set "{foo}users:#{i}", i
15
+ assert_equal r1.node_for("foo").id, r2.node_for("foo").id
16
+ assert_equal r1.node_for("foo").id, r3.node_for("foo").id
27
17
  end
28
18
 
29
- assert [0, 100] == r.nodes.map { |node| node.keys.size }
30
- end
19
+ def test_allows_clustering_of_keys
20
+ r = Redis::Distributed.new(NODES)
21
+ r.add_node("redis://localhost:#{PORT}/14")
22
+ r.flushdb
31
23
 
32
- test "distributes keys if no clustering is used" do |r|
33
- r.add_node("redis://localhost:6379/14")
34
- r.flushdb
24
+ 100.times do |i|
25
+ r.set "{foo}users:#{i}", i
26
+ end
35
27
 
36
- r.set "users:1", 1
37
- r.set "users:4", 4
28
+ assert_equal [0, 100], r.nodes.map { |node| node.keys.size }
29
+ end
38
30
 
39
- assert [1, 1] == r.nodes.map { |node| node.keys.size }
40
- end
31
+ def test_distributes_keys_if_no_clustering_is_used
32
+ r.add_node("redis://localhost:#{PORT}/14")
33
+ r.flushdb
41
34
 
42
- test "allows passing a custom tag extractor" do |r|
43
- r = Redis::Distributed.new(NODES, :tag => /^(.+?):/)
44
- r.add_node("redis://localhost:6379/14")
45
- r.flushdb
35
+ r.set "users:1", 1
36
+ r.set "users:4", 4
46
37
 
47
- 100.times do |i|
48
- r.set "foo:users:#{i}", i
38
+ assert_equal [1, 1], r.nodes.map { |node| node.keys.size }
49
39
  end
50
40
 
51
- assert [0, 100] == r.nodes.map { |node| node.keys.size }
41
+ def test_allows_passing_a_custom_tag_extractor
42
+ r = Redis::Distributed.new(NODES, :tag => /^(.+?):/)
43
+ r.add_node("redis://localhost:#{PORT}/14")
44
+ r.flushdb
45
+
46
+ 100.times do |i|
47
+ r.set "foo:users:#{i}", i
48
+ end
49
+
50
+ assert_equal [0, 100], r.nodes.map { |node| node.keys.size }
51
+ end
52
52
  end
@@ -1,23 +1,26 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
- require "redis/distributed"
3
+ require "helper"
5
4
 
6
- setup do
7
- log = StringIO.new
8
- init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
- end
5
+ class TestDistributedPersistenceControlCommands < Test::Unit::TestCase
6
+
7
+ include Helper::Distributed
10
8
 
11
- test "SAVE and BGSAVE" do |r|
12
- assert_nothing_raised do
13
- r.save
9
+ def test_save
10
+ redis_mock(:save => lambda { "+SAVE" }) do |redis|
11
+ assert_equal ["SAVE"], redis.save
12
+ end
14
13
  end
15
14
 
16
- assert_nothing_raised do
17
- r.bgsave
15
+ def test_bgsave
16
+ redis_mock(:bgsave => lambda { "+BGSAVE" }) do |redis|
17
+ assert_equal ["BGSAVE"], redis.bgsave
18
+ end
18
19
  end
19
- end
20
20
 
21
- test "LASTSAVE" do |r|
22
- assert r.lastsave.all? { |t| Time.at(t) <= Time.now }
21
+ def test_lastsave
22
+ redis_mock(:lastsave => lambda { "+LASTSAVE" }) do |redis|
23
+ assert_equal ["LASTSAVE"], redis.lastsave
24
+ end
25
+ end
23
26
  end