]>
Commit | Line | Data |
---|---|---|
7f7499ee | 1 | start_server {tags {"zset"}} { |
4774a53b PN |
2 | proc create_zset {key items} { |
3 | r del $key | |
4 | foreach {score entry} $items { | |
5 | r zadd $key $score $entry | |
6 | } | |
7 | } | |
8 | ||
9ec4ea20 PN |
9 | proc basics {encoding} { |
10 | if {$encoding == "ziplist"} { | |
11 | r config set zset-max-ziplist-entries 128 | |
12 | r config set zset-max-ziplist-value 64 | |
100ed062 | 13 | } elseif {$encoding == "skiplist"} { |
9ec4ea20 PN |
14 | r config set zset-max-ziplist-entries 0 |
15 | r config set zset-max-ziplist-value 0 | |
16 | } else { | |
17 | puts "Unknown sorted set encoding" | |
18 | exit | |
19 | } | |
184d74ab | 20 | |
9ec4ea20 PN |
21 | test "Check encoding - $encoding" { |
22 | r del ztmp | |
23 | r zadd ztmp 10 x | |
24 | assert_encoding $encoding ztmp | |
25 | } | |
184d74ab | 26 | |
9ec4ea20 PN |
27 | test "ZSET basic ZADD and score update - $encoding" { |
28 | r del ztmp | |
29 | r zadd ztmp 10 x | |
30 | r zadd ztmp 20 y | |
31 | r zadd ztmp 30 z | |
32 | assert_equal {x y z} [r zrange ztmp 0 -1] | |
33 | ||
34 | r zadd ztmp 1 y | |
35 | assert_equal {y x z} [r zrange ztmp 0 -1] | |
98578b57 | 36 | } |
9ec4ea20 PN |
37 | |
38 | test "ZSET element can't be set to NaN with ZADD - $encoding" { | |
d93f9a86 | 39 | assert_error "*not*float*" {r zadd myzset nan abc} |
98578b57 | 40 | } |
98578b57 | 41 | |
9ec4ea20 | 42 | test "ZSET element can't be set to NaN with ZINCRBY" { |
d93f9a86 | 43 | assert_error "*not*float*" {r zadd myzset nan abc} |
9ec4ea20 PN |
44 | } |
45 | ||
46 | test "ZINCRBY calls leading to NaN result in error" { | |
47 | r zincrby myzset +inf abc | |
48 | assert_error "*NaN*" {r zincrby myzset -inf abc} | |
49 | } | |
faa2a80f | 50 | |
51 | test {ZADD - Variadic version base case} { | |
52 | r del myzset | |
53 | list [r zadd myzset 10 a 20 b 30 c] [r zrange myzset 0 -1 withscores] | |
54 | } {3 {a 10 b 20 c 30}} | |
55 | ||
56 | test {ZADD - Return value is the number of actually added items} { | |
57 | list [r zadd myzset 5 x 20 b 30 c] [r zrange myzset 0 -1 withscores] | |
58 | } {1 {x 5 a 10 b 20 c 30}} | |
59 | ||
60 | test {ZADD - Variadic version does not add nothing on single parsing err} { | |
61 | r del myzset | |
62 | catch {r zadd myzset 10 a 20 b 30.badscore c} e | |
d93f9a86 | 63 | assert_match {*ERR*not*float*} $e |
faa2a80f | 64 | r exists myzset |
65 | } {0} | |
66 | ||
67 | test {ZADD - Variadic version will raise error on missing arg} { | |
68 | r del myzset | |
69 | catch {r zadd myzset 10 a 20 b 30 c 40} e | |
70 | assert_match {*ERR*syntax*} $e | |
71 | } | |
72 | ||
73 | test {ZINCRBY does not work variadic even if shares ZADD implementation} { | |
74 | r del myzset | |
75 | catch {r zincrby myzset 10 a 20 b 30 c} e | |
76 | assert_match {*ERR*wrong*number*arg*} $e | |
77 | } | |
9ec4ea20 PN |
78 | |
79 | test "ZCARD basics - $encoding" { | |
80 | assert_equal 3 [r zcard ztmp] | |
81 | assert_equal 0 [r zcard zdoesntexist] | |
82 | } | |
83 | ||
04a10b1a PN |
84 | test "ZREM removes key after last element is removed" { |
85 | r del ztmp | |
86 | r zadd ztmp 10 x | |
87 | r zadd ztmp 20 y | |
88 | ||
89 | assert_equal 1 [r exists ztmp] | |
90 | assert_equal 0 [r zrem ztmp z] | |
91 | assert_equal 1 [r zrem ztmp y] | |
92 | assert_equal 1 [r zrem ztmp x] | |
93 | assert_equal 0 [r exists ztmp] | |
94 | } | |
95 | ||
b002546b | 96 | test "ZREM variadic version" { |
97 | r del ztmp | |
98 | r zadd ztmp 10 a 20 b 30 c | |
99 | assert_equal 2 [r zrem ztmp x y a b k] | |
100 | assert_equal 0 [r zrem ztmp foo bar] | |
101 | assert_equal 1 [r zrem ztmp c] | |
102 | r exists ztmp | |
103 | } {0} | |
104 | ||
105 | test "ZREM variadic version -- remove elements after key deletion" { | |
106 | r del ztmp | |
107 | r zadd ztmp 10 a 20 b 30 c | |
108 | r zrem ztmp a b c d e f g | |
109 | } {3} | |
110 | ||
9ec4ea20 PN |
111 | test "ZRANGE basics - $encoding" { |
112 | r del ztmp | |
113 | r zadd ztmp 1 a | |
114 | r zadd ztmp 2 b | |
115 | r zadd ztmp 3 c | |
116 | r zadd ztmp 4 d | |
117 | ||
118 | assert_equal {a b c d} [r zrange ztmp 0 -1] | |
119 | assert_equal {a b c} [r zrange ztmp 0 -2] | |
120 | assert_equal {b c d} [r zrange ztmp 1 -1] | |
121 | assert_equal {b c} [r zrange ztmp 1 -2] | |
122 | assert_equal {c d} [r zrange ztmp -2 -1] | |
123 | assert_equal {c} [r zrange ztmp -2 -2] | |
124 | ||
125 | # out of range start index | |
126 | assert_equal {a b c} [r zrange ztmp -5 2] | |
127 | assert_equal {a b} [r zrange ztmp -5 1] | |
128 | assert_equal {} [r zrange ztmp 5 -1] | |
129 | assert_equal {} [r zrange ztmp 5 -2] | |
130 | ||
131 | # out of range end index | |
132 | assert_equal {a b c d} [r zrange ztmp 0 5] | |
133 | assert_equal {b c d} [r zrange ztmp 1 5] | |
134 | assert_equal {} [r zrange ztmp 0 -5] | |
135 | assert_equal {} [r zrange ztmp 1 -5] | |
136 | ||
137 | # withscores | |
138 | assert_equal {a 1 b 2 c 3 d 4} [r zrange ztmp 0 -1 withscores] | |
139 | } | |
140 | ||
141 | test "ZREVRANGE basics - $encoding" { | |
142 | r del ztmp | |
143 | r zadd ztmp 1 a | |
144 | r zadd ztmp 2 b | |
145 | r zadd ztmp 3 c | |
146 | r zadd ztmp 4 d | |
147 | ||
148 | assert_equal {d c b a} [r zrevrange ztmp 0 -1] | |
149 | assert_equal {d c b} [r zrevrange ztmp 0 -2] | |
150 | assert_equal {c b a} [r zrevrange ztmp 1 -1] | |
151 | assert_equal {c b} [r zrevrange ztmp 1 -2] | |
152 | assert_equal {b a} [r zrevrange ztmp -2 -1] | |
153 | assert_equal {b} [r zrevrange ztmp -2 -2] | |
154 | ||
155 | # out of range start index | |
156 | assert_equal {d c b} [r zrevrange ztmp -5 2] | |
157 | assert_equal {d c} [r zrevrange ztmp -5 1] | |
158 | assert_equal {} [r zrevrange ztmp 5 -1] | |
159 | assert_equal {} [r zrevrange ztmp 5 -2] | |
160 | ||
161 | # out of range end index | |
162 | assert_equal {d c b a} [r zrevrange ztmp 0 5] | |
163 | assert_equal {c b a} [r zrevrange ztmp 1 5] | |
164 | assert_equal {} [r zrevrange ztmp 0 -5] | |
165 | assert_equal {} [r zrevrange ztmp 1 -5] | |
166 | ||
167 | # withscores | |
168 | assert_equal {d 4 c 3 b 2 a 1} [r zrevrange ztmp 0 -1 withscores] | |
169 | } | |
170 | ||
171 | test "ZRANK/ZREVRANK basics - $encoding" { | |
172 | r del zranktmp | |
173 | r zadd zranktmp 10 x | |
174 | r zadd zranktmp 20 y | |
175 | r zadd zranktmp 30 z | |
176 | assert_equal 0 [r zrank zranktmp x] | |
177 | assert_equal 1 [r zrank zranktmp y] | |
178 | assert_equal 2 [r zrank zranktmp z] | |
179 | assert_equal "" [r zrank zranktmp foo] | |
180 | assert_equal 2 [r zrevrank zranktmp x] | |
181 | assert_equal 1 [r zrevrank zranktmp y] | |
182 | assert_equal 0 [r zrevrank zranktmp z] | |
183 | assert_equal "" [r zrevrank zranktmp foo] | |
184 | } | |
185 | ||
186 | test "ZRANK - after deletion - $encoding" { | |
187 | r zrem zranktmp y | |
188 | assert_equal 0 [r zrank zranktmp x] | |
189 | assert_equal 1 [r zrank zranktmp z] | |
190 | } | |
191 | ||
192 | test "ZINCRBY - can create a new sorted set - $encoding" { | |
193 | r del zset | |
194 | r zincrby zset 1 foo | |
195 | assert_equal {foo} [r zrange zset 0 -1] | |
196 | assert_equal 1 [r zscore zset foo] | |
197 | } | |
198 | ||
199 | test "ZINCRBY - increment and decrement - $encoding" { | |
200 | r zincrby zset 2 foo | |
201 | r zincrby zset 1 bar | |
202 | assert_equal {bar foo} [r zrange zset 0 -1] | |
203 | ||
204 | r zincrby zset 10 bar | |
205 | r zincrby zset -5 foo | |
206 | r zincrby zset -5 bar | |
207 | assert_equal {foo bar} [r zrange zset 0 -1] | |
208 | ||
209 | assert_equal -2 [r zscore zset foo] | |
210 | assert_equal 6 [r zscore zset bar] | |
211 | } | |
212 | ||
213 | proc create_default_zset {} { | |
214 | create_zset zset {-inf a 1 b 2 c 3 d 4 e 5 f +inf g} | |
215 | } | |
216 | ||
217 | test "ZRANGEBYSCORE/ZREVRANGEBYSCORE/ZCOUNT basics" { | |
218 | create_default_zset | |
219 | ||
220 | # inclusive range | |
221 | assert_equal {a b c} [r zrangebyscore zset -inf 2] | |
222 | assert_equal {b c d} [r zrangebyscore zset 0 3] | |
223 | assert_equal {d e f} [r zrangebyscore zset 3 6] | |
224 | assert_equal {e f g} [r zrangebyscore zset 4 +inf] | |
225 | assert_equal {c b a} [r zrevrangebyscore zset 2 -inf] | |
226 | assert_equal {d c b} [r zrevrangebyscore zset 3 0] | |
227 | assert_equal {f e d} [r zrevrangebyscore zset 6 3] | |
228 | assert_equal {g f e} [r zrevrangebyscore zset +inf 4] | |
229 | assert_equal 3 [r zcount zset 0 3] | |
230 | ||
231 | # exclusive range | |
232 | assert_equal {b} [r zrangebyscore zset (-inf (2] | |
233 | assert_equal {b c} [r zrangebyscore zset (0 (3] | |
234 | assert_equal {e f} [r zrangebyscore zset (3 (6] | |
235 | assert_equal {f} [r zrangebyscore zset (4 (+inf] | |
236 | assert_equal {b} [r zrevrangebyscore zset (2 (-inf] | |
237 | assert_equal {c b} [r zrevrangebyscore zset (3 (0] | |
238 | assert_equal {f e} [r zrevrangebyscore zset (6 (3] | |
239 | assert_equal {f} [r zrevrangebyscore zset (+inf (4] | |
240 | assert_equal 2 [r zcount zset (0 (3] | |
241 | ||
242 | # test empty ranges | |
243 | r zrem zset a | |
244 | r zrem zset g | |
245 | ||
246 | # inclusive | |
247 | assert_equal {} [r zrangebyscore zset 4 2] | |
248 | assert_equal {} [r zrangebyscore zset 6 +inf] | |
249 | assert_equal {} [r zrangebyscore zset -inf -6] | |
250 | assert_equal {} [r zrevrangebyscore zset +inf 6] | |
251 | assert_equal {} [r zrevrangebyscore zset -6 -inf] | |
252 | ||
253 | # exclusive | |
254 | assert_equal {} [r zrangebyscore zset (4 (2] | |
255 | assert_equal {} [r zrangebyscore zset 2 (2] | |
256 | assert_equal {} [r zrangebyscore zset (2 2] | |
257 | assert_equal {} [r zrangebyscore zset (6 (+inf] | |
258 | assert_equal {} [r zrangebyscore zset (-inf (-6] | |
259 | assert_equal {} [r zrevrangebyscore zset (+inf (6] | |
260 | assert_equal {} [r zrevrangebyscore zset (-6 (-inf] | |
261 | ||
262 | # empty inner range | |
263 | assert_equal {} [r zrangebyscore zset 2.4 2.6] | |
264 | assert_equal {} [r zrangebyscore zset (2.4 2.6] | |
265 | assert_equal {} [r zrangebyscore zset 2.4 (2.6] | |
266 | assert_equal {} [r zrangebyscore zset (2.4 (2.6] | |
267 | } | |
268 | ||
269 | test "ZRANGEBYSCORE with WITHSCORES" { | |
270 | create_default_zset | |
271 | assert_equal {b 1 c 2 d 3} [r zrangebyscore zset 0 3 withscores] | |
272 | assert_equal {d 3 c 2 b 1} [r zrevrangebyscore zset 3 0 withscores] | |
273 | } | |
274 | ||
275 | test "ZRANGEBYSCORE with LIMIT" { | |
276 | create_default_zset | |
277 | assert_equal {b c} [r zrangebyscore zset 0 10 LIMIT 0 2] | |
278 | assert_equal {d e f} [r zrangebyscore zset 0 10 LIMIT 2 3] | |
279 | assert_equal {d e f} [r zrangebyscore zset 0 10 LIMIT 2 10] | |
280 | assert_equal {} [r zrangebyscore zset 0 10 LIMIT 20 10] | |
281 | assert_equal {f e} [r zrevrangebyscore zset 10 0 LIMIT 0 2] | |
282 | assert_equal {d c b} [r zrevrangebyscore zset 10 0 LIMIT 2 3] | |
283 | assert_equal {d c b} [r zrevrangebyscore zset 10 0 LIMIT 2 10] | |
284 | assert_equal {} [r zrevrangebyscore zset 10 0 LIMIT 20 10] | |
285 | } | |
286 | ||
287 | test "ZRANGEBYSCORE with LIMIT and WITHSCORES" { | |
288 | create_default_zset | |
289 | assert_equal {e 4 f 5} [r zrangebyscore zset 2 5 LIMIT 2 3 WITHSCORES] | |
290 | assert_equal {d 3 c 2} [r zrevrangebyscore zset 5 2 LIMIT 2 3 WITHSCORES] | |
291 | } | |
292 | ||
293 | test "ZRANGEBYSCORE with non-value min or max" { | |
d93f9a86 | 294 | assert_error "*not*float*" {r zrangebyscore fooz str 1} |
295 | assert_error "*not*float*" {r zrangebyscore fooz 1 str} | |
296 | assert_error "*not*float*" {r zrangebyscore fooz 1 NaN} | |
9ec4ea20 PN |
297 | } |
298 | ||
299 | test "ZREMRANGEBYSCORE basics" { | |
300 | proc remrangebyscore {min max} { | |
301 | create_zset zset {1 a 2 b 3 c 4 d 5 e} | |
04a10b1a | 302 | assert_equal 1 [r exists zset] |
9ec4ea20 | 303 | r zremrangebyscore zset $min $max |
98578b57 | 304 | } |
9ec4ea20 PN |
305 | |
306 | # inner range | |
307 | assert_equal 3 [remrangebyscore 2 4] | |
308 | assert_equal {a e} [r zrange zset 0 -1] | |
309 | ||
310 | # start underflow | |
311 | assert_equal 1 [remrangebyscore -10 1] | |
312 | assert_equal {b c d e} [r zrange zset 0 -1] | |
313 | ||
314 | # end overflow | |
315 | assert_equal 1 [remrangebyscore 5 10] | |
316 | assert_equal {a b c d} [r zrange zset 0 -1] | |
317 | ||
318 | # switch min and max | |
319 | assert_equal 0 [remrangebyscore 4 2] | |
320 | assert_equal {a b c d e} [r zrange zset 0 -1] | |
321 | ||
322 | # -inf to mid | |
323 | assert_equal 3 [remrangebyscore -inf 3] | |
324 | assert_equal {d e} [r zrange zset 0 -1] | |
325 | ||
326 | # mid to +inf | |
327 | assert_equal 3 [remrangebyscore 3 +inf] | |
328 | assert_equal {a b} [r zrange zset 0 -1] | |
329 | ||
330 | # -inf to +inf | |
331 | assert_equal 5 [remrangebyscore -inf +inf] | |
332 | assert_equal {} [r zrange zset 0 -1] | |
333 | ||
334 | # exclusive min | |
335 | assert_equal 4 [remrangebyscore (1 5] | |
336 | assert_equal {a} [r zrange zset 0 -1] | |
337 | assert_equal 3 [remrangebyscore (2 5] | |
338 | assert_equal {a b} [r zrange zset 0 -1] | |
339 | ||
340 | # exclusive max | |
341 | assert_equal 4 [remrangebyscore 1 (5] | |
342 | assert_equal {e} [r zrange zset 0 -1] | |
343 | assert_equal 3 [remrangebyscore 1 (4] | |
344 | assert_equal {d e} [r zrange zset 0 -1] | |
345 | ||
346 | # exclusive min and max | |
347 | assert_equal 3 [remrangebyscore (1 (5] | |
348 | assert_equal {a e} [r zrange zset 0 -1] | |
04a10b1a PN |
349 | |
350 | # destroy when empty | |
351 | assert_equal 5 [remrangebyscore 1 5] | |
352 | assert_equal 0 [r exists zset] | |
9ec4ea20 PN |
353 | } |
354 | ||
355 | test "ZREMRANGEBYSCORE with non-value min or max" { | |
d93f9a86 | 356 | assert_error "*not*float*" {r zremrangebyscore fooz str 1} |
357 | assert_error "*not*float*" {r zremrangebyscore fooz 1 str} | |
358 | assert_error "*not*float*" {r zremrangebyscore fooz 1 NaN} | |
9ec4ea20 PN |
359 | } |
360 | ||
361 | test "ZREMRANGEBYRANK basics" { | |
362 | proc remrangebyrank {min max} { | |
363 | create_zset zset {1 a 2 b 3 c 4 d 5 e} | |
04a10b1a | 364 | assert_equal 1 [r exists zset] |
9ec4ea20 | 365 | r zremrangebyrank zset $min $max |
98578b57 | 366 | } |
9ec4ea20 PN |
367 | |
368 | # inner range | |
369 | assert_equal 3 [remrangebyrank 1 3] | |
370 | assert_equal {a e} [r zrange zset 0 -1] | |
371 | ||
372 | # start underflow | |
373 | assert_equal 1 [remrangebyrank -10 0] | |
374 | assert_equal {b c d e} [r zrange zset 0 -1] | |
375 | ||
376 | # start overflow | |
377 | assert_equal 0 [remrangebyrank 10 -1] | |
378 | assert_equal {a b c d e} [r zrange zset 0 -1] | |
379 | ||
380 | # end underflow | |
381 | assert_equal 0 [remrangebyrank 0 -10] | |
382 | assert_equal {a b c d e} [r zrange zset 0 -1] | |
383 | ||
384 | # end overflow | |
385 | assert_equal 5 [remrangebyrank 0 10] | |
386 | assert_equal {} [r zrange zset 0 -1] | |
04a10b1a PN |
387 | |
388 | # destroy when empty | |
389 | assert_equal 5 [remrangebyrank 0 4] | |
390 | assert_equal 0 [r exists zset] | |
9ec4ea20 PN |
391 | } |
392 | ||
393 | test "ZUNIONSTORE against non-existing key doesn't set destination - $encoding" { | |
394 | r del zseta | |
395 | assert_equal 0 [r zunionstore dst_key 1 zseta] | |
396 | assert_equal 0 [r exists dst_key] | |
397 | } | |
398 | ||
521ddcce | 399 | test "ZUNIONSTORE with empty set - $encoding" { |
400 | r del zseta zsetb | |
401 | r zadd zseta 1 a | |
402 | r zadd zseta 2 b | |
403 | r zunionstore zsetc 2 zseta zsetb | |
404 | r zrange zsetc 0 -1 withscores | |
405 | } {a 1 b 2} | |
406 | ||
9ec4ea20 PN |
407 | test "ZUNIONSTORE basics - $encoding" { |
408 | r del zseta zsetb zsetc | |
409 | r zadd zseta 1 a | |
410 | r zadd zseta 2 b | |
411 | r zadd zseta 3 c | |
412 | r zadd zsetb 1 b | |
413 | r zadd zsetb 2 c | |
414 | r zadd zsetb 3 d | |
415 | ||
416 | assert_equal 4 [r zunionstore zsetc 2 zseta zsetb] | |
417 | assert_equal {a 1 b 3 d 3 c 5} [r zrange zsetc 0 -1 withscores] | |
418 | } | |
419 | ||
420 | test "ZUNIONSTORE with weights - $encoding" { | |
421 | assert_equal 4 [r zunionstore zsetc 2 zseta zsetb weights 2 3] | |
422 | assert_equal {a 2 b 7 d 9 c 12} [r zrange zsetc 0 -1 withscores] | |
423 | } | |
424 | ||
425 | test "ZUNIONSTORE with a regular set and weights - $encoding" { | |
426 | r del seta | |
427 | r sadd seta a | |
428 | r sadd seta b | |
429 | r sadd seta c | |
430 | ||
431 | assert_equal 4 [r zunionstore zsetc 2 seta zsetb weights 2 3] | |
432 | assert_equal {a 2 b 5 c 8 d 9} [r zrange zsetc 0 -1 withscores] | |
433 | } | |
434 | ||
435 | test "ZUNIONSTORE with AGGREGATE MIN - $encoding" { | |
436 | assert_equal 4 [r zunionstore zsetc 2 zseta zsetb aggregate min] | |
437 | assert_equal {a 1 b 1 c 2 d 3} [r zrange zsetc 0 -1 withscores] | |
438 | } | |
439 | ||
440 | test "ZUNIONSTORE with AGGREGATE MAX - $encoding" { | |
441 | assert_equal 4 [r zunionstore zsetc 2 zseta zsetb aggregate max] | |
442 | assert_equal {a 1 b 2 c 3 d 3} [r zrange zsetc 0 -1 withscores] | |
443 | } | |
444 | ||
445 | test "ZINTERSTORE basics - $encoding" { | |
446 | assert_equal 2 [r zinterstore zsetc 2 zseta zsetb] | |
447 | assert_equal {b 3 c 5} [r zrange zsetc 0 -1 withscores] | |
448 | } | |
449 | ||
450 | test "ZINTERSTORE with weights - $encoding" { | |
451 | assert_equal 2 [r zinterstore zsetc 2 zseta zsetb weights 2 3] | |
452 | assert_equal {b 7 c 12} [r zrange zsetc 0 -1 withscores] | |
453 | } | |
454 | ||
455 | test "ZINTERSTORE with a regular set and weights - $encoding" { | |
456 | r del seta | |
457 | r sadd seta a | |
458 | r sadd seta b | |
459 | r sadd seta c | |
460 | assert_equal 2 [r zinterstore zsetc 2 seta zsetb weights 2 3] | |
461 | assert_equal {b 5 c 8} [r zrange zsetc 0 -1 withscores] | |
462 | } | |
463 | ||
464 | test "ZINTERSTORE with AGGREGATE MIN - $encoding" { | |
465 | assert_equal 2 [r zinterstore zsetc 2 zseta zsetb aggregate min] | |
466 | assert_equal {b 1 c 2} [r zrange zsetc 0 -1 withscores] | |
467 | } | |
468 | ||
469 | test "ZINTERSTORE with AGGREGATE MAX - $encoding" { | |
470 | assert_equal 2 [r zinterstore zsetc 2 zseta zsetb aggregate max] | |
471 | assert_equal {b 2 c 3} [r zrange zsetc 0 -1 withscores] | |
472 | } | |
473 | ||
474 | foreach cmd {ZUNIONSTORE ZINTERSTORE} { | |
475 | test "$cmd with +inf/-inf scores - $encoding" { | |
476 | r del zsetinf1 zsetinf2 | |
477 | ||
478 | r zadd zsetinf1 +inf key | |
479 | r zadd zsetinf2 +inf key | |
480 | r $cmd zsetinf3 2 zsetinf1 zsetinf2 | |
481 | assert_equal inf [r zscore zsetinf3 key] | |
482 | ||
483 | r zadd zsetinf1 -inf key | |
484 | r zadd zsetinf2 +inf key | |
485 | r $cmd zsetinf3 2 zsetinf1 zsetinf2 | |
486 | assert_equal 0 [r zscore zsetinf3 key] | |
487 | ||
488 | r zadd zsetinf1 +inf key | |
489 | r zadd zsetinf2 -inf key | |
490 | r $cmd zsetinf3 2 zsetinf1 zsetinf2 | |
491 | assert_equal 0 [r zscore zsetinf3 key] | |
492 | ||
493 | r zadd zsetinf1 -inf key | |
494 | r zadd zsetinf2 -inf key | |
495 | r $cmd zsetinf3 2 zsetinf1 zsetinf2 | |
496 | assert_equal -inf [r zscore zsetinf3 key] | |
98578b57 | 497 | } |
9ec4ea20 PN |
498 | |
499 | test "$cmd with NaN weights $encoding" { | |
500 | r del zsetinf1 zsetinf2 | |
501 | ||
502 | r zadd zsetinf1 1.0 key | |
503 | r zadd zsetinf2 1.0 key | |
d93f9a86 | 504 | assert_error "*weight*not*float*" { |
9ec4ea20 | 505 | r $cmd zsetinf3 2 zsetinf1 zsetinf2 weights nan nan |
98578b57 PN |
506 | } |
507 | } | |
508 | } | |
25bb8a44 | 509 | } |
98578b57 | 510 | |
9ec4ea20 | 511 | basics ziplist |
100ed062 | 512 | basics skiplist |
9ec4ea20 | 513 | |
af9aed25 | 514 | test {ZINTERSTORE regression with two sets, intset+hashtable} { |
515 | r del seta setb setc | |
516 | r sadd set1 a | |
517 | r sadd set2 10 | |
518 | r zinterstore set3 2 set1 set2 | |
519 | } {0} | |
520 | ||
9678c375 | 521 | test {ZUNIONSTORE regression, should not create NaN in scores} { |
522 | r zadd z -inf neginf | |
523 | r zunionstore out 1 z weights 0 | |
524 | r zrange out 0 -1 withscores | |
525 | } {neginf 0} | |
526 | ||
9ec4ea20 PN |
527 | proc stressers {encoding} { |
528 | if {$encoding == "ziplist"} { | |
529 | # Little extra to allow proper fuzzing in the sorting stresser | |
530 | r config set zset-max-ziplist-entries 256 | |
531 | r config set zset-max-ziplist-value 64 | |
532 | set elements 128 | |
100ed062 | 533 | } elseif {$encoding == "skiplist"} { |
9ec4ea20 PN |
534 | r config set zset-max-ziplist-entries 0 |
535 | r config set zset-max-ziplist-value 0 | |
30cf7be6 | 536 | if {$::accurate} {set elements 1000} else {set elements 100} |
9ec4ea20 PN |
537 | } else { |
538 | puts "Unknown sorted set encoding" | |
539 | exit | |
540 | } | |
25bb8a44 | 541 | |
9ec4ea20 PN |
542 | test "ZSCORE - $encoding" { |
543 | r del zscoretest | |
544 | set aux {} | |
545 | for {set i 0} {$i < $elements} {incr i} { | |
546 | set score [expr rand()] | |
547 | lappend aux $score | |
548 | r zadd zscoretest $score $i | |
549 | } | |
25bb8a44 | 550 | |
9ec4ea20 PN |
551 | assert_encoding $encoding zscoretest |
552 | for {set i 0} {$i < $elements} {incr i} { | |
553 | assert_equal [lindex $aux $i] [r zscore zscoretest $i] | |
554 | } | |
555 | } | |
25bb8a44 | 556 | |
9ec4ea20 PN |
557 | test "ZSCORE after a DEBUG RELOAD - $encoding" { |
558 | r del zscoretest | |
559 | set aux {} | |
560 | for {set i 0} {$i < $elements} {incr i} { | |
561 | set score [expr rand()] | |
562 | lappend aux $score | |
563 | r zadd zscoretest $score $i | |
564 | } | |
98578b57 | 565 | |
9ec4ea20 PN |
566 | r debug reload |
567 | assert_encoding $encoding zscoretest | |
568 | for {set i 0} {$i < $elements} {incr i} { | |
569 | assert_equal [lindex $aux $i] [r zscore zscoretest $i] | |
570 | } | |
571 | } | |
7236fdb2 | 572 | |
9ec4ea20 PN |
573 | test "ZSET sorting stresser - $encoding" { |
574 | set delta 0 | |
575 | for {set test 0} {$test < 2} {incr test} { | |
576 | unset -nocomplain auxarray | |
577 | array set auxarray {} | |
578 | set auxlist {} | |
579 | r del myzset | |
580 | for {set i 0} {$i < $elements} {incr i} { | |
581 | if {$test == 0} { | |
582 | set score [expr rand()] | |
583 | } else { | |
584 | set score [expr int(rand()*10)] | |
585 | } | |
586 | set auxarray($i) $score | |
587 | r zadd myzset $score $i | |
588 | # Random update | |
589 | if {[expr rand()] < .2} { | |
590 | set j [expr int(rand()*1000)] | |
591 | if {$test == 0} { | |
592 | set score [expr rand()] | |
593 | } else { | |
594 | set score [expr int(rand()*10)] | |
595 | } | |
596 | set auxarray($j) $score | |
597 | r zadd myzset $score $j | |
598 | } | |
599 | } | |
600 | foreach {item score} [array get auxarray] { | |
601 | lappend auxlist [list $score $item] | |
602 | } | |
603 | set sorted [lsort -command zlistAlikeSort $auxlist] | |
604 | set auxlist {} | |
605 | foreach x $sorted { | |
606 | lappend auxlist [lindex $x 1] | |
607 | } | |
608 | ||
609 | assert_encoding $encoding myzset | |
610 | set fromredis [r zrange myzset 0 -1] | |
611 | set delta 0 | |
612 | for {set i 0} {$i < [llength $fromredis]} {incr i} { | |
613 | if {[lindex $fromredis $i] != [lindex $auxlist $i]} { | |
614 | incr delta | |
615 | } | |
616 | } | |
617 | } | |
618 | assert_equal 0 $delta | |
619 | } | |
620 | ||
621 | test "ZRANGEBYSCORE fuzzy test, 100 ranges in $elements element sorted set - $encoding" { | |
7f7499ee PN |
622 | set err {} |
623 | r del zset | |
9ec4ea20 | 624 | for {set i 0} {$i < $elements} {incr i} { |
7f7499ee | 625 | r zadd zset [expr rand()] $i |
98578b57 | 626 | } |
9ec4ea20 PN |
627 | |
628 | assert_encoding $encoding zset | |
7f7499ee PN |
629 | for {set i 0} {$i < 100} {incr i} { |
630 | set min [expr rand()] | |
631 | set max [expr rand()] | |
632 | if {$min > $max} { | |
633 | set aux $min | |
634 | set min $max | |
635 | set max $aux | |
636 | } | |
637 | set low [r zrangebyscore zset -inf $min] | |
638 | set ok [r zrangebyscore zset $min $max] | |
639 | set high [r zrangebyscore zset $max +inf] | |
640 | set lowx [r zrangebyscore zset -inf ($min] | |
641 | set okx [r zrangebyscore zset ($min ($max] | |
642 | set highx [r zrangebyscore zset ($max +inf] | |
643 | ||
644 | if {[r zcount zset -inf $min] != [llength $low]} { | |
645 | append err "Error, len does not match zcount\n" | |
646 | } | |
647 | if {[r zcount zset $min $max] != [llength $ok]} { | |
648 | append err "Error, len does not match zcount\n" | |
649 | } | |
650 | if {[r zcount zset $max +inf] != [llength $high]} { | |
651 | append err "Error, len does not match zcount\n" | |
652 | } | |
653 | if {[r zcount zset -inf ($min] != [llength $lowx]} { | |
654 | append err "Error, len does not match zcount\n" | |
655 | } | |
656 | if {[r zcount zset ($min ($max] != [llength $okx]} { | |
657 | append err "Error, len does not match zcount\n" | |
658 | } | |
659 | if {[r zcount zset ($max +inf] != [llength $highx]} { | |
660 | append err "Error, len does not match zcount\n" | |
661 | } | |
98578b57 | 662 | |
7f7499ee PN |
663 | foreach x $low { |
664 | set score [r zscore zset $x] | |
665 | if {$score > $min} { | |
666 | append err "Error, score for $x is $score > $min\n" | |
667 | } | |
98578b57 | 668 | } |
7f7499ee PN |
669 | foreach x $lowx { |
670 | set score [r zscore zset $x] | |
671 | if {$score >= $min} { | |
672 | append err "Error, score for $x is $score >= $min\n" | |
673 | } | |
98578b57 | 674 | } |
7f7499ee PN |
675 | foreach x $ok { |
676 | set score [r zscore zset $x] | |
677 | if {$score < $min || $score > $max} { | |
678 | append err "Error, score for $x is $score outside $min-$max range\n" | |
679 | } | |
98578b57 | 680 | } |
7f7499ee PN |
681 | foreach x $okx { |
682 | set score [r zscore zset $x] | |
683 | if {$score <= $min || $score >= $max} { | |
684 | append err "Error, score for $x is $score outside $min-$max open range\n" | |
685 | } | |
98578b57 | 686 | } |
7f7499ee PN |
687 | foreach x $high { |
688 | set score [r zscore zset $x] | |
689 | if {$score < $max} { | |
690 | append err "Error, score for $x is $score < $max\n" | |
691 | } | |
98578b57 | 692 | } |
7f7499ee PN |
693 | foreach x $highx { |
694 | set score [r zscore zset $x] | |
695 | if {$score <= $max} { | |
696 | append err "Error, score for $x is $score <= $max\n" | |
697 | } | |
98578b57 PN |
698 | } |
699 | } | |
9ec4ea20 | 700 | assert_equal {} $err |
4774a53b PN |
701 | } |
702 | ||
9ec4ea20 | 703 | test "ZSETs skiplist implementation backlink consistency test - $encoding" { |
7f7499ee | 704 | set diff 0 |
7f7499ee PN |
705 | for {set j 0} {$j < $elements} {incr j} { |
706 | r zadd myzset [expr rand()] "Element-$j" | |
707 | r zrem myzset "Element-[expr int(rand()*$elements)]" | |
98578b57 | 708 | } |
9ec4ea20 PN |
709 | |
710 | assert_encoding $encoding myzset | |
7f7499ee PN |
711 | set l1 [r zrange myzset 0 -1] |
712 | set l2 [r zrevrange myzset 0 -1] | |
713 | for {set j 0} {$j < [llength $l1]} {incr j} { | |
714 | if {[lindex $l1 $j] ne [lindex $l2 end-$j]} { | |
715 | incr diff | |
716 | } | |
98578b57 | 717 | } |
9ec4ea20 PN |
718 | assert_equal 0 $diff |
719 | } | |
7f7499ee | 720 | |
9ec4ea20 | 721 | test "ZSETs ZRANK augmented skip list stress testing - $encoding" { |
7f7499ee PN |
722 | set err {} |
723 | r del myzset | |
9ec4ea20 PN |
724 | for {set k 0} {$k < 2000} {incr k} { |
725 | set i [expr {$k % $elements}] | |
7f7499ee PN |
726 | if {[expr rand()] < .2} { |
727 | r zrem myzset $i | |
728 | } else { | |
729 | set score [expr rand()] | |
730 | r zadd myzset $score $i | |
9ec4ea20 | 731 | assert_encoding $encoding myzset |
7f7499ee | 732 | } |
9ec4ea20 | 733 | |
7f7499ee PN |
734 | set card [r zcard myzset] |
735 | if {$card > 0} { | |
736 | set index [randomInt $card] | |
737 | set ele [lindex [r zrange myzset $index $index] 0] | |
738 | set rank [r zrank myzset $ele] | |
739 | if {$rank != $index} { | |
740 | set err "$ele RANK is wrong! ($rank != $index)" | |
741 | break | |
742 | } | |
98578b57 PN |
743 | } |
744 | } | |
9ec4ea20 PN |
745 | assert_equal {} $err |
746 | } | |
673e1fb7 | 747 | } |
5fc9229c | 748 | |
9ec4ea20 PN |
749 | tags {"slow"} { |
750 | stressers ziplist | |
100ed062 | 751 | stressers skiplist |
673e1fb7 | 752 | } |
98578b57 | 753 | } |