redis 3.0.0.rc1 → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
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