redis 4.0.1 → 4.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +17 -29
- data/.travis/Gemfile +5 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +5 -0
- data/README.md +1 -1
- data/bin/build +71 -0
- data/lib/redis.rb +198 -12
- data/lib/redis/client.rb +26 -12
- data/lib/redis/cluster.rb +285 -0
- data/lib/redis/cluster/command.rb +81 -0
- data/lib/redis/cluster/command_loader.rb +32 -0
- data/lib/redis/cluster/key_slot_converter.rb +72 -0
- data/lib/redis/cluster/node.rb +104 -0
- data/lib/redis/cluster/node_key.rb +35 -0
- data/lib/redis/cluster/node_loader.rb +35 -0
- data/lib/redis/cluster/option.rb +76 -0
- data/lib/redis/cluster/slot.rb +69 -0
- data/lib/redis/cluster/slot_loader.rb +47 -0
- data/lib/redis/connection/ruby.rb +5 -2
- data/lib/redis/distributed.rb +10 -2
- data/lib/redis/errors.rb +46 -0
- data/lib/redis/pipeline.rb +9 -1
- data/lib/redis/version.rb +1 -1
- data/makefile +54 -22
- data/redis.gemspec +2 -1
- data/test/client_test.rb +17 -0
- data/test/cluster_abnormal_state_test.rb +38 -0
- data/test/cluster_blocking_commands_test.rb +15 -0
- data/test/cluster_client_internals_test.rb +77 -0
- data/test/cluster_client_key_hash_tags_test.rb +88 -0
- data/test/cluster_client_options_test.rb +147 -0
- data/test/cluster_client_pipelining_test.rb +59 -0
- data/test/cluster_client_replicas_test.rb +36 -0
- data/test/cluster_client_slots_test.rb +94 -0
- data/test/cluster_client_transactions_test.rb +71 -0
- data/test/cluster_commands_on_cluster_test.rb +165 -0
- data/test/cluster_commands_on_connection_test.rb +40 -0
- data/test/cluster_commands_on_geo_test.rb +74 -0
- data/test/cluster_commands_on_hashes_test.rb +11 -0
- data/test/cluster_commands_on_hyper_log_log_test.rb +17 -0
- data/test/cluster_commands_on_keys_test.rb +134 -0
- data/test/cluster_commands_on_lists_test.rb +15 -0
- data/test/cluster_commands_on_pub_sub_test.rb +101 -0
- data/test/cluster_commands_on_scripting_test.rb +56 -0
- data/test/cluster_commands_on_server_test.rb +221 -0
- data/test/cluster_commands_on_sets_test.rb +39 -0
- data/test/cluster_commands_on_sorted_sets_test.rb +35 -0
- data/test/cluster_commands_on_streams_test.rb +196 -0
- data/test/cluster_commands_on_strings_test.rb +15 -0
- data/test/cluster_commands_on_transactions_test.rb +41 -0
- data/test/cluster_commands_on_value_types_test.rb +14 -0
- data/test/commands_on_geo_test.rb +116 -0
- data/test/commands_on_hashes_test.rb +2 -14
- data/test/commands_on_hyper_log_log_test.rb +2 -14
- data/test/commands_on_lists_test.rb +2 -13
- data/test/commands_on_sets_test.rb +2 -70
- data/test/commands_on_sorted_sets_test.rb +2 -145
- data/test/commands_on_strings_test.rb +2 -94
- data/test/commands_on_value_types_test.rb +36 -0
- data/test/distributed_blocking_commands_test.rb +8 -0
- data/test/distributed_commands_on_hashes_test.rb +16 -3
- data/test/distributed_commands_on_hyper_log_log_test.rb +8 -13
- data/test/distributed_commands_on_lists_test.rb +4 -5
- data/test/distributed_commands_on_sets_test.rb +45 -46
- data/test/distributed_commands_on_sorted_sets_test.rb +51 -8
- data/test/distributed_commands_on_strings_test.rb +10 -0
- data/test/distributed_commands_on_value_types_test.rb +36 -0
- data/test/helper.rb +176 -32
- data/test/internals_test.rb +20 -1
- data/test/lint/blocking_commands.rb +40 -16
- data/test/lint/hashes.rb +41 -0
- data/test/lint/hyper_log_log.rb +15 -1
- data/test/lint/lists.rb +16 -0
- data/test/lint/sets.rb +142 -0
- data/test/lint/sorted_sets.rb +183 -2
- data/test/lint/strings.rb +102 -0
- data/test/pipelining_commands_test.rb +8 -0
- data/test/support/cluster/orchestrator.rb +199 -0
- data/test/support/redis_mock.rb +1 -1
- data/test/transactions_test.rb +10 -0
- metadata +81 -2
@@ -0,0 +1,221 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
# ruby -w -Itest test/cluster_commands_on_server_test.rb
|
6
|
+
# @see https://redis.io/commands#server
|
7
|
+
class TestClusterCommandsOnServer < Test::Unit::TestCase
|
8
|
+
include Helper::Cluster
|
9
|
+
|
10
|
+
def test_bgrewriteaof
|
11
|
+
assert_equal 'Background append only file rewriting started', redis.bgrewriteaof
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_bgsave
|
15
|
+
redis_cluster_mock(bgsave: ->(*_) { '+OK' }) do |redis|
|
16
|
+
assert_equal 'OK', redis.bgsave
|
17
|
+
end
|
18
|
+
|
19
|
+
err_msg = 'ERR An AOF log rewriting in progress: '\
|
20
|
+
"can't BGSAVE right now. "\
|
21
|
+
'Use BGSAVE SCHEDULE in order to schedule a BGSAVE whenever possible.'
|
22
|
+
|
23
|
+
redis_cluster_mock(bgsave: ->(*_) { "-Error #{err_msg}" }) do |redis|
|
24
|
+
assert_raise(Redis::Cluster::CommandErrorCollection, 'Command error replied on any node') do
|
25
|
+
redis.bgsave
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_client_kill
|
31
|
+
redis_cluster_mock(client: ->(*_) { '-Error ERR No such client' }) do |redis|
|
32
|
+
assert_raise(Redis::CommandError, 'ERR No such client') do
|
33
|
+
redis.client(:kill, '127.0.0.1:6379')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
redis_cluster_mock(client: ->(*_) { '+OK' }) do |redis|
|
38
|
+
assert_equal 'OK', redis.client(:kill, '127.0.0.1:6379')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_client_list
|
43
|
+
a_client_info = redis.client(:list).first
|
44
|
+
actual = a_client_info.keys.sort
|
45
|
+
expected = %w[addr age cmd db events fd flags id idle multi name obl oll omem psub qbuf qbuf-free sub]
|
46
|
+
assert_equal expected, actual
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_client_getname
|
50
|
+
redis.client(:setname, 'my-client-01')
|
51
|
+
assert_equal 'my-client-01', redis.client(:getname)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_client_pause
|
55
|
+
assert_equal 'OK', redis.client(:pause, 0)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_client_reply
|
59
|
+
target_version('3.2.0') do
|
60
|
+
assert_equal 'OK', redis.client(:reply, 'ON')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_client_setname
|
65
|
+
assert_equal 'OK', redis.client(:setname, 'my-client-01')
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_command
|
69
|
+
assert_instance_of Array, redis.command
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_command_count
|
73
|
+
assert_true(redis.command(:count) > 0)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_command_getkeys
|
77
|
+
assert_equal %w[a c e], redis.command(:getkeys, :mset, 'a', 'b', 'c', 'd', 'e', 'f')
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_command_info
|
81
|
+
expected = [
|
82
|
+
['get', 2, %w[readonly fast], 1, 1, 1],
|
83
|
+
['set', -3, %w[write denyoom], 1, 1, 1],
|
84
|
+
['eval', -3, %w[noscript movablekeys], 0, 0, 0]
|
85
|
+
]
|
86
|
+
assert_equal expected, redis.command(:info, :get, :set, :eval)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_config_get
|
90
|
+
expected_keys = if version < '3.2.0'
|
91
|
+
%w[hash-max-ziplist-entries list-max-ziplist-entries set-max-intset-entries zset-max-ziplist-entries]
|
92
|
+
else
|
93
|
+
%w[hash-max-ziplist-entries set-max-intset-entries zset-max-ziplist-entries]
|
94
|
+
end
|
95
|
+
|
96
|
+
assert_equal expected_keys, redis.config(:get, '*max-*-entries*').keys.sort
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_config_rewrite
|
100
|
+
redis_cluster_mock(config: ->(*_) { '-Error ERR Rewriting config file: Permission denied' }) do |redis|
|
101
|
+
assert_raise(Redis::Cluster::CommandErrorCollection, 'Command error replied on any node') do
|
102
|
+
redis.config(:rewrite)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
redis_cluster_mock(config: ->(*_) { '+OK' }) do |redis|
|
107
|
+
assert_equal 'OK', redis.config(:rewrite)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_config_set
|
112
|
+
assert_equal 'OK', redis.config(:set, 'hash-max-ziplist-entries', 512)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_config_resetstat
|
116
|
+
assert_equal 'OK', redis.config(:resetstat)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_config_db_size
|
120
|
+
10.times { |i| redis.set("key#{i}", 1) }
|
121
|
+
assert_equal 10, redis.dbsize
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_debug_object
|
125
|
+
# DEBUG OBJECT is a debugging command that should not be used by clients.
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_debug_segfault
|
129
|
+
# DEBUG SEGFAULT performs an invalid memory access that crashes Redis.
|
130
|
+
# It is used to simulate bugs during the development.
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_flushall
|
134
|
+
assert_equal 'OK', redis.flushall
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_flushdb
|
138
|
+
assert_equal 'OK', redis.flushdb
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_info
|
142
|
+
assert_equal({ 'cluster_enabled' => '1' }, redis.info(:cluster))
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_lastsave
|
146
|
+
assert_instance_of Array, redis.lastsave
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_memory_doctor
|
150
|
+
target_version('4.0.0') do
|
151
|
+
assert_instance_of String, redis.memory(:doctor)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_memory_help
|
156
|
+
target_version('4.0.0') do
|
157
|
+
assert_instance_of Array, redis.memory(:help)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_memory_malloc_stats
|
162
|
+
target_version('4.0.0') do
|
163
|
+
assert_instance_of String, redis.memory('malloc-stats')
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_memory_purge
|
168
|
+
target_version('4.0.0') do
|
169
|
+
assert_equal 'OK', redis.memory(:purge)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_memory_stats
|
174
|
+
target_version('4.0.0') do
|
175
|
+
assert_instance_of Array, redis.memory(:stats)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_memory_usage
|
180
|
+
target_version('4.0.0') do
|
181
|
+
redis.set('key1', 'Hello World')
|
182
|
+
assert_equal 61, redis.memory(:usage, 'key1')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_monitor
|
187
|
+
# Add MONITOR command test
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_role
|
191
|
+
assert_equal %w[master master master], redis.role.map(&:first)
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_save
|
195
|
+
assert_equal 'OK', redis.save
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_shutdown
|
199
|
+
assert_raise(Redis::Cluster::OrchestrationCommandNotSupported, 'SHUTDOWN command should be...') do
|
200
|
+
redis.shutdown
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_slaveof
|
205
|
+
assert_raise(Redis::CommandError, 'ERR SLAVEOF not allowed in cluster mode.') do
|
206
|
+
redis.slaveof(:no, :one)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_slowlog
|
211
|
+
assert_instance_of Array, redis.slowlog(:get, 1)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_sync
|
215
|
+
# Internal command used for replication
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_time
|
219
|
+
assert_instance_of Array, redis.time
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require_relative 'lint/sets'
|
5
|
+
|
6
|
+
# ruby -w -Itest test/cluster_commands_on_sets_test.rb
|
7
|
+
# @see https://redis.io/commands#set
|
8
|
+
class TestClusterCommandsOnSets < Test::Unit::TestCase
|
9
|
+
include Helper::Cluster
|
10
|
+
include Lint::Sets
|
11
|
+
|
12
|
+
def test_sdiff
|
13
|
+
assert_raise(Redis::CommandError) { super }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_sdiffstore
|
17
|
+
assert_raise(Redis::CommandError) { super }
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_sinter
|
21
|
+
assert_raise(Redis::CommandError) { super }
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_sinterstore
|
25
|
+
assert_raise(Redis::CommandError) { super }
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_smove
|
29
|
+
assert_raise(Redis::CommandError) { super }
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_sunion
|
33
|
+
assert_raise(Redis::CommandError) { super }
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_sunionstore
|
37
|
+
assert_raise(Redis::CommandError) { super }
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require_relative 'lint/sorted_sets'
|
5
|
+
|
6
|
+
# ruby -w -Itest test/cluster_commands_on_sorted_sets_test.rb
|
7
|
+
# @see https://redis.io/commands#sorted_set
|
8
|
+
class TestClusterCommandsOnSortedSets < Test::Unit::TestCase
|
9
|
+
include Helper::Cluster
|
10
|
+
include Lint::SortedSets
|
11
|
+
|
12
|
+
def test_zinterstore
|
13
|
+
assert_raise(Redis::CommandError) { super }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_zinterstore_with_aggregate
|
17
|
+
assert_raise(Redis::CommandError) { super }
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_zinterstore_with_weights
|
21
|
+
assert_raise(Redis::CommandError) { super }
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_zunionstore
|
25
|
+
assert_raise(Redis::CommandError) { super }
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_zunionstore_with_aggregate
|
29
|
+
assert_raise(Redis::CommandError) { super }
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_zunionstore_with_weights
|
33
|
+
assert_raise(Redis::CommandError) { super }
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
# ruby -w -Itest test/cluster_commands_on_streams_test.rb
|
6
|
+
# @see https://redis.io/commands#stream
|
7
|
+
class TestClusterCommandsOnStreams < Test::Unit::TestCase
|
8
|
+
include Helper::Cluster
|
9
|
+
|
10
|
+
MIN_REDIS_VERSION = '4.9.0'
|
11
|
+
ENTRY_ID_FORMAT = /\d+-\d+/
|
12
|
+
|
13
|
+
def setup
|
14
|
+
super
|
15
|
+
add_some_entries_to_streams_without_hashtag
|
16
|
+
add_some_entries_to_streams_with_hashtag
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_some_entries_to_streams_without_hashtag
|
20
|
+
target_version(MIN_REDIS_VERSION) do
|
21
|
+
redis.xadd('stream1', '*', 'name', 'John', 'surname', 'Connor')
|
22
|
+
redis.xadd('stream1', '*', 'name', 'Sarah', 'surname', 'Connor')
|
23
|
+
redis.xadd('stream1', '*', 'name', 'Miles', 'surname', 'Dyson')
|
24
|
+
redis.xadd('stream1', '*', 'name', 'Peter', 'surname', 'Silberman')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_some_entries_to_streams_with_hashtag
|
29
|
+
target_version(MIN_REDIS_VERSION) do
|
30
|
+
redis.xadd('{stream}1', '*', 'name', 'John', 'surname', 'Connor')
|
31
|
+
redis.xadd('{stream}1', '*', 'name', 'Sarah', 'surname', 'Connor')
|
32
|
+
redis.xadd('{stream}1', '*', 'name', 'Miles', 'surname', 'Dyson')
|
33
|
+
redis.xadd('{stream}1', '*', 'name', 'Peter', 'surname', 'Silberman')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_stream_entry(actual, expected_name, expected_surname)
|
38
|
+
actual_key = actual.keys.first
|
39
|
+
actual_values = actual[actual_key]
|
40
|
+
|
41
|
+
assert_match ENTRY_ID_FORMAT, actual_key
|
42
|
+
assert_equal expected_name, actual_values['name']
|
43
|
+
assert_equal expected_surname, actual_values['surname']
|
44
|
+
end
|
45
|
+
|
46
|
+
def assert_stream_pending(actual, expected_size_of_group, expected_consumer_name, expected_size_of_consumer)
|
47
|
+
assert_equal expected_size_of_group, actual[:size]
|
48
|
+
assert_match ENTRY_ID_FORMAT, actual[:min_entry_id]
|
49
|
+
assert_match ENTRY_ID_FORMAT, actual[:max_entry_id]
|
50
|
+
assert_equal({ expected_consumer_name => expected_size_of_consumer }, actual[:consumers])
|
51
|
+
end
|
52
|
+
|
53
|
+
# TODO: Remove this helper method when we implement streams interfaces
|
54
|
+
def hashify_stream_entries(reply)
|
55
|
+
reply.map do |entry_id, values|
|
56
|
+
[entry_id, Hash[values.each_slice(2).to_a]]
|
57
|
+
end.to_h
|
58
|
+
end
|
59
|
+
|
60
|
+
# TODO: Remove this helper method when we implement streams interfaces
|
61
|
+
def hashify_streams(reply)
|
62
|
+
reply.map do |stream_key, entries|
|
63
|
+
[stream_key, hashify_stream_entries(entries)]
|
64
|
+
end.to_h
|
65
|
+
end
|
66
|
+
|
67
|
+
# TODO: Remove this helper method when we implement streams interfaces
|
68
|
+
def hashify_stream_pendings(reply)
|
69
|
+
{
|
70
|
+
size: reply.first,
|
71
|
+
min_entry_id: reply[1],
|
72
|
+
max_entry_id: reply[2],
|
73
|
+
consumers: Hash[reply[3]]
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_xadd
|
78
|
+
target_version(MIN_REDIS_VERSION) do
|
79
|
+
assert_match ENTRY_ID_FORMAT, redis.xadd('mystream', '*', 'type', 'T-800', 'model', '101')
|
80
|
+
assert_match ENTRY_ID_FORMAT, redis.xadd('my{stream}', '*', 'type', 'T-1000')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_xrange
|
85
|
+
target_version(MIN_REDIS_VERSION) do
|
86
|
+
actual = redis.xrange('stream1', '-', '+', 'COUNT', 1)
|
87
|
+
actual = hashify_stream_entries(actual) # TODO: Remove this step when we implement streams interfaces
|
88
|
+
assert_stream_entry(actual, 'John', 'Connor')
|
89
|
+
|
90
|
+
actual = redis.xrange('{stream}1', '-', '+', 'COUNT', 1)
|
91
|
+
actual = hashify_stream_entries(actual) # TODO: Remove this step when we implement streams interfaces
|
92
|
+
assert_stream_entry(actual, 'John', 'Connor')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_xrevrange
|
97
|
+
target_version(MIN_REDIS_VERSION) do
|
98
|
+
actual = redis.xrevrange('stream1', '+', '-', 'COUNT', 1)
|
99
|
+
actual = hashify_stream_entries(actual) # TODO: Remove this step when we implement streams interfaces
|
100
|
+
assert_stream_entry(actual, 'Peter', 'Silberman')
|
101
|
+
|
102
|
+
actual = redis.xrevrange('{stream}1', '+', '-', 'COUNT', 1)
|
103
|
+
actual = hashify_stream_entries(actual) # TODO: Remove this step when we implement streams interfaces
|
104
|
+
assert_stream_entry(actual, 'Peter', 'Silberman')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_xlen
|
109
|
+
target_version(MIN_REDIS_VERSION) do
|
110
|
+
assert_equal 4, redis.xlen('stream1')
|
111
|
+
assert_equal 4, redis.xlen('{stream}1')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_xread
|
116
|
+
target_version(MIN_REDIS_VERSION) do
|
117
|
+
# non blocking without hashtag
|
118
|
+
actual = redis.xread('COUNT', 1, 'STREAMS', 'stream1', 0)
|
119
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
120
|
+
assert_equal 'stream1', actual.keys.first
|
121
|
+
assert_stream_entry(actual['stream1'], 'John', 'Connor')
|
122
|
+
|
123
|
+
# blocking without hashtag
|
124
|
+
actual = redis.xread('COUNT', 1, 'BLOCK', 1, 'STREAMS', 'stream1', 0)
|
125
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
126
|
+
assert_equal 'stream1', actual.keys.first
|
127
|
+
assert_stream_entry(actual['stream1'], 'John', 'Connor')
|
128
|
+
|
129
|
+
# non blocking with hashtag
|
130
|
+
actual = redis.xread('COUNT', 1, 'STREAMS', '{stream}1', 0)
|
131
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
132
|
+
assert_equal '{stream}1', actual.keys.first
|
133
|
+
assert_stream_entry(actual['{stream}1'], 'John', 'Connor')
|
134
|
+
|
135
|
+
# blocking with hashtag
|
136
|
+
actual = redis.xread('COUNT', 1, 'BLOCK', 1, 'STREAMS', '{stream}1', 0)
|
137
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
138
|
+
assert_equal '{stream}1', actual.keys.first
|
139
|
+
assert_stream_entry(actual['{stream}1'], 'John', 'Connor')
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_xreadgroup
|
144
|
+
target_version(MIN_REDIS_VERSION) do
|
145
|
+
# non blocking without hashtag
|
146
|
+
redis.xgroup('create', 'stream1', 'mygroup1', '$')
|
147
|
+
add_some_entries_to_streams_without_hashtag
|
148
|
+
actual = redis.xreadgroup('GROUP', 'mygroup1', 'T-1000', 'COUNT', 1, 'STREAMS', 'stream1', '>')
|
149
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
150
|
+
assert_equal 'stream1', actual.keys.first
|
151
|
+
assert_stream_entry(actual['stream1'], 'John', 'Connor')
|
152
|
+
|
153
|
+
# blocking without hashtag
|
154
|
+
redis.xgroup('create', 'stream1', 'mygroup2', '$')
|
155
|
+
add_some_entries_to_streams_without_hashtag
|
156
|
+
actual = redis.xreadgroup('GROUP', 'mygroup2', 'T-800', 'COUNT', 1, 'BLOCK', 1, 'STREAMS', 'stream1', '>')
|
157
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
158
|
+
assert_equal 'stream1', actual.keys.first
|
159
|
+
assert_stream_entry(actual['stream1'], 'John', 'Connor')
|
160
|
+
|
161
|
+
# non blocking with hashtag
|
162
|
+
redis.xgroup('create', '{stream}1', 'mygroup3', '$')
|
163
|
+
add_some_entries_to_streams_with_hashtag
|
164
|
+
actual = redis.xreadgroup('GROUP', 'mygroup3', 'T-1000', 'COUNT', 1, 'STREAMS', '{stream}1', '>')
|
165
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
166
|
+
assert_equal '{stream}1', actual.keys.first
|
167
|
+
assert_stream_entry(actual['{stream}1'], 'John', 'Connor')
|
168
|
+
|
169
|
+
# blocking with hashtag
|
170
|
+
redis.xgroup('create', '{stream}1', 'mygroup4', '$')
|
171
|
+
add_some_entries_to_streams_with_hashtag
|
172
|
+
actual = redis.xreadgroup('GROUP', 'mygroup4', 'T-800', 'COUNT', 1, 'BLOCK', 1, 'STREAMS', '{stream}1', '>')
|
173
|
+
actual = hashify_streams(actual) # TODO: Remove this step when we implement streams interfaces
|
174
|
+
assert_equal '{stream}1', actual.keys.first
|
175
|
+
assert_stream_entry(actual['{stream}1'], 'John', 'Connor')
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_xpending
|
180
|
+
target_version(MIN_REDIS_VERSION) do
|
181
|
+
redis.xgroup('create', 'stream1', 'mygroup1', '$')
|
182
|
+
add_some_entries_to_streams_without_hashtag
|
183
|
+
redis.xreadgroup('GROUP', 'mygroup1', 'T-800', 'COUNT', 1, 'STREAMS', 'stream1', '>')
|
184
|
+
actual = redis.xpending('stream1', 'mygroup1')
|
185
|
+
actual = hashify_stream_pendings(actual) # TODO: Remove this step when we implement streams interfaces
|
186
|
+
assert_stream_pending(actual, 1, 'T-800', '1')
|
187
|
+
|
188
|
+
redis.xgroup('create', '{stream}1', 'mygroup2', '$')
|
189
|
+
add_some_entries_to_streams_with_hashtag
|
190
|
+
redis.xreadgroup('GROUP', 'mygroup2', 'T-800', 'COUNT', 1, 'STREAMS', '{stream}1', '>')
|
191
|
+
actual = redis.xpending('{stream}1', 'mygroup2')
|
192
|
+
actual = hashify_stream_pendings(actual) # TODO: Remove this step when we implement streams interfaces
|
193
|
+
assert_stream_pending(actual, 1, 'T-800', '1')
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|