]> git.saurik.com Git - redis.git/blame - tests/unit/type/zset.tcl
more tests for zrange and zrevrange; fix behavior for out-of-range negative end index
[redis.git] / tests / unit / type / zset.tcl
CommitLineData
7f7499ee 1start_server {tags {"zset"}} {
98578b57
PN
2 test {ZSET basic ZADD and score update} {
3 r zadd ztmp 10 x
4 r zadd ztmp 20 y
5 r zadd ztmp 30 z
6 set aux1 [r zrange ztmp 0 -1]
7 r zadd ztmp 1 y
8 set aux2 [r zrange ztmp 0 -1]
9 list $aux1 $aux2
10 } {{x y z} {y x z}}
11
12 test {ZCARD basics} {
13 r zcard ztmp
14 } {3}
15
16 test {ZCARD non existing key} {
17 r zcard ztmp-blabla
18 } {0}
19
184d74ab
PN
20 test "ZRANGE basics" {
21 r del ztmp
22 r zadd ztmp 1 a
23 r zadd ztmp 2 b
24 r zadd ztmp 3 c
25 r zadd ztmp 4 d
26
27 assert_equal {a b c d} [r zrange ztmp 0 -1]
28 assert_equal {a b c} [r zrange ztmp 0 -2]
29 assert_equal {b c d} [r zrange ztmp 1 -1]
30 assert_equal {b c} [r zrange ztmp 1 -2]
31 assert_equal {c d} [r zrange ztmp -2 -1]
32 assert_equal {c} [r zrange ztmp -2 -2]
33
34 # out of range start index
35 assert_equal {a b c} [r zrange ztmp -5 2]
36 assert_equal {a b} [r zrange ztmp -5 1]
37 assert_equal {} [r zrange ztmp 5 -1]
38 assert_equal {} [r zrange ztmp 5 -2]
39
40 # out of range end index
41 assert_equal {a b c d} [r zrange ztmp 0 5]
42 assert_equal {b c d} [r zrange ztmp 1 5]
43 assert_equal {} [r zrange ztmp 0 -5]
44 assert_equal {} [r zrange ztmp 1 -5]
45
46 # withscores
47 assert_equal {a 1 b 2 c 3 d 4} [r zrange ztmp 0 -1 withscores]
48 }
49
50 test "ZREVRANGE basics" {
51 r del ztmp
52 r zadd ztmp 1 a
53 r zadd ztmp 2 b
54 r zadd ztmp 3 c
55 r zadd ztmp 4 d
56
57 assert_equal {d c b a} [r zrevrange ztmp 0 -1]
58 assert_equal {d c b} [r zrevrange ztmp 0 -2]
59 assert_equal {c b a} [r zrevrange ztmp 1 -1]
60 assert_equal {c b} [r zrevrange ztmp 1 -2]
61 assert_equal {b a} [r zrevrange ztmp -2 -1]
62 assert_equal {b} [r zrevrange ztmp -2 -2]
63
64 # out of range start index
65 assert_equal {d c b} [r zrevrange ztmp -5 2]
66 assert_equal {d c} [r zrevrange ztmp -5 1]
67 assert_equal {} [r zrevrange ztmp 5 -1]
68 assert_equal {} [r zrevrange ztmp 5 -2]
69
70 # out of range end index
71 assert_equal {d c b a} [r zrevrange ztmp 0 5]
72 assert_equal {c b a} [r zrevrange ztmp 1 5]
73 assert_equal {} [r zrevrange ztmp 0 -5]
74 assert_equal {} [r zrevrange ztmp 1 -5]
75
76 # withscores
77 assert_equal {d 4 c 3 b 2 a 1} [r zrevrange ztmp 0 -1 withscores]
78 }
79
98578b57
PN
80 test {ZRANK basics} {
81 r zadd zranktmp 10 x
82 r zadd zranktmp 20 y
83 r zadd zranktmp 30 z
84 list [r zrank zranktmp x] [r zrank zranktmp y] [r zrank zranktmp z]
85 } {0 1 2}
86
87 test {ZREVRANK basics} {
88 list [r zrevrank zranktmp x] [r zrevrank zranktmp y] [r zrevrank zranktmp z]
89 } {2 1 0}
90
91 test {ZRANK - after deletion} {
92 r zrem zranktmp y
93 list [r zrank zranktmp x] [r zrank zranktmp z]
94 } {0 1}
95
96 test {ZSCORE} {
97 set aux {}
98 set err {}
99 for {set i 0} {$i < 1000} {incr i} {
100 set score [expr rand()]
101 lappend aux $score
102 r zadd zscoretest $score $i
103 }
104 for {set i 0} {$i < 1000} {incr i} {
105 if {[r zscore zscoretest $i] != [lindex $aux $i]} {
106 set err "Expected score was [lindex $aux $i] but got [r zscore zscoretest $i] for element $i"
107 break
108 }
109 }
110 set _ $err
111 } {}
112
113 test {ZSCORE after a DEBUG RELOAD} {
114 set aux {}
115 set err {}
116 r del zscoretest
117 for {set i 0} {$i < 1000} {incr i} {
118 set score [expr rand()]
119 lappend aux $score
120 r zadd zscoretest $score $i
121 }
122 r debug reload
123 for {set i 0} {$i < 1000} {incr i} {
124 if {[r zscore zscoretest $i] != [lindex $aux $i]} {
125 set err "Expected score was [lindex $aux $i] but got [r zscore zscoretest $i] for element $i"
126 break
127 }
128 }
129 set _ $err
130 } {}
131
98578b57
PN
132 test {ZSETs stress tester - sorting is working well?} {
133 set delta 0
134 for {set test 0} {$test < 2} {incr test} {
135 unset -nocomplain auxarray
136 array set auxarray {}
137 set auxlist {}
138 r del myzset
139 for {set i 0} {$i < 1000} {incr i} {
140 if {$test == 0} {
141 set score [expr rand()]
142 } else {
143 set score [expr int(rand()*10)]
144 }
145 set auxarray($i) $score
146 r zadd myzset $score $i
147 # Random update
148 if {[expr rand()] < .2} {
149 set j [expr int(rand()*1000)]
150 if {$test == 0} {
151 set score [expr rand()]
152 } else {
153 set score [expr int(rand()*10)]
154 }
155 set auxarray($j) $score
156 r zadd myzset $score $j
157 }
158 }
159 foreach {item score} [array get auxarray] {
160 lappend auxlist [list $score $item]
161 }
162 set sorted [lsort -command zlistAlikeSort $auxlist]
163 set auxlist {}
164 foreach x $sorted {
165 lappend auxlist [lindex $x 1]
166 }
167 set fromredis [r zrange myzset 0 -1]
168 set delta 0
169 for {set i 0} {$i < [llength $fromredis]} {incr i} {
170 if {[lindex $fromredis $i] != [lindex $auxlist $i]} {
171 incr delta
172 }
173 }
174 }
175 format $delta
176 } {0}
177
178 test {ZINCRBY - can create a new sorted set} {
179 r del zset
180 r zincrby zset 1 foo
181 list [r zrange zset 0 -1] [r zscore zset foo]
182 } {foo 1}
183
184 test {ZINCRBY - increment and decrement} {
185 r zincrby zset 2 foo
186 r zincrby zset 1 bar
187 set v1 [r zrange zset 0 -1]
188 r zincrby zset 10 bar
189 r zincrby zset -5 foo
190 r zincrby zset -5 bar
191 set v2 [r zrange zset 0 -1]
192 list $v1 $v2 [r zscore zset foo] [r zscore zset bar]
193 } {{bar foo} {foo bar} -2 6}
194
195 test {ZRANGEBYSCORE and ZCOUNT basics} {
196 r del zset
197 r zadd zset 1 a
198 r zadd zset 2 b
199 r zadd zset 3 c
200 r zadd zset 4 d
201 r zadd zset 5 e
202 list [r zrangebyscore zset 2 4] [r zrangebyscore zset (2 (4] \
203 [r zcount zset 2 4] [r zcount zset (2 (4]
204 } {{b c d} c 3 1}
205
206 test {ZRANGEBYSCORE withscores} {
207 r del zset
208 r zadd zset 1 a
209 r zadd zset 2 b
210 r zadd zset 3 c
211 r zadd zset 4 d
212 r zadd zset 5 e
213 r zrangebyscore zset 2 4 withscores
214 } {b 2 c 3 d 4}
215
7f7499ee
PN
216 tags {"slow"} {
217 test {ZRANGEBYSCORE fuzzy test, 100 ranges in 1000 elements sorted set} {
218 set err {}
219 r del zset
220 for {set i 0} {$i < 1000} {incr i} {
221 r zadd zset [expr rand()] $i
98578b57 222 }
7f7499ee
PN
223 for {set i 0} {$i < 100} {incr i} {
224 set min [expr rand()]
225 set max [expr rand()]
226 if {$min > $max} {
227 set aux $min
228 set min $max
229 set max $aux
230 }
231 set low [r zrangebyscore zset -inf $min]
232 set ok [r zrangebyscore zset $min $max]
233 set high [r zrangebyscore zset $max +inf]
234 set lowx [r zrangebyscore zset -inf ($min]
235 set okx [r zrangebyscore zset ($min ($max]
236 set highx [r zrangebyscore zset ($max +inf]
237
238 if {[r zcount zset -inf $min] != [llength $low]} {
239 append err "Error, len does not match zcount\n"
240 }
241 if {[r zcount zset $min $max] != [llength $ok]} {
242 append err "Error, len does not match zcount\n"
243 }
244 if {[r zcount zset $max +inf] != [llength $high]} {
245 append err "Error, len does not match zcount\n"
246 }
247 if {[r zcount zset -inf ($min] != [llength $lowx]} {
248 append err "Error, len does not match zcount\n"
249 }
250 if {[r zcount zset ($min ($max] != [llength $okx]} {
251 append err "Error, len does not match zcount\n"
252 }
253 if {[r zcount zset ($max +inf] != [llength $highx]} {
254 append err "Error, len does not match zcount\n"
255 }
98578b57 256
7f7499ee
PN
257 foreach x $low {
258 set score [r zscore zset $x]
259 if {$score > $min} {
260 append err "Error, score for $x is $score > $min\n"
261 }
98578b57 262 }
7f7499ee
PN
263 foreach x $lowx {
264 set score [r zscore zset $x]
265 if {$score >= $min} {
266 append err "Error, score for $x is $score >= $min\n"
267 }
98578b57 268 }
7f7499ee
PN
269 foreach x $ok {
270 set score [r zscore zset $x]
271 if {$score < $min || $score > $max} {
272 append err "Error, score for $x is $score outside $min-$max range\n"
273 }
98578b57 274 }
7f7499ee
PN
275 foreach x $okx {
276 set score [r zscore zset $x]
277 if {$score <= $min || $score >= $max} {
278 append err "Error, score for $x is $score outside $min-$max open range\n"
279 }
98578b57 280 }
7f7499ee
PN
281 foreach x $high {
282 set score [r zscore zset $x]
283 if {$score < $max} {
284 append err "Error, score for $x is $score < $max\n"
285 }
98578b57 286 }
7f7499ee
PN
287 foreach x $highx {
288 set score [r zscore zset $x]
289 if {$score <= $max} {
290 append err "Error, score for $x is $score <= $max\n"
291 }
98578b57
PN
292 }
293 }
7f7499ee
PN
294 set _ $err
295 } {}
296 }
98578b57
PN
297
298 test {ZRANGEBYSCORE with LIMIT} {
299 r del zset
300 r zadd zset 1 a
301 r zadd zset 2 b
302 r zadd zset 3 c
303 r zadd zset 4 d
304 r zadd zset 5 e
305 list \
306 [r zrangebyscore zset 0 10 LIMIT 0 2] \
307 [r zrangebyscore zset 0 10 LIMIT 2 3] \
308 [r zrangebyscore zset 0 10 LIMIT 2 10] \
309 [r zrangebyscore zset 0 10 LIMIT 20 10]
310 } {{a b} {c d e} {c d e} {}}
311
312 test {ZRANGEBYSCORE with LIMIT and withscores} {
313 r del zset
314 r zadd zset 10 a
315 r zadd zset 20 b
316 r zadd zset 30 c
317 r zadd zset 40 d
318 r zadd zset 50 e
319 r zrangebyscore zset 20 50 LIMIT 2 3 withscores
320 } {d 40 e 50}
321
322 test {ZREMRANGEBYSCORE basics} {
323 r del zset
324 r zadd zset 1 a
325 r zadd zset 2 b
326 r zadd zset 3 c
327 r zadd zset 4 d
328 r zadd zset 5 e
329 list [r zremrangebyscore zset 2 4] [r zrange zset 0 -1]
330 } {3 {a e}}
331
332 test {ZREMRANGEBYSCORE from -inf to +inf} {
333 r del zset
334 r zadd zset 1 a
335 r zadd zset 2 b
336 r zadd zset 3 c
337 r zadd zset 4 d
338 r zadd zset 5 e
339 list [r zremrangebyscore zset -inf +inf] [r zrange zset 0 -1]
340 } {5 {}}
341
342 test {ZREMRANGEBYRANK basics} {
343 r del zset
344 r zadd zset 1 a
345 r zadd zset 2 b
346 r zadd zset 3 c
347 r zadd zset 4 d
348 r zadd zset 5 e
349 list [r zremrangebyrank zset 1 3] [r zrange zset 0 -1]
350 } {3 {a e}}
351
5d373da9 352 test {ZUNIONSTORE against non-existing key doesn't set destination} {
98578b57 353 r del zseta
5d373da9 354 list [r zunionstore dst_key 1 zseta] [r exists dst_key]
98578b57
PN
355 } {0 0}
356
5d373da9 357 test {ZUNIONSTORE basics} {
98578b57
PN
358 r del zseta zsetb zsetc
359 r zadd zseta 1 a
360 r zadd zseta 2 b
361 r zadd zseta 3 c
362 r zadd zsetb 1 b
363 r zadd zsetb 2 c
364 r zadd zsetb 3 d
5d373da9 365 list [r zunionstore zsetc 2 zseta zsetb] [r zrange zsetc 0 -1 withscores]
98578b57
PN
366 } {4 {a 1 b 3 d 3 c 5}}
367
5d373da9 368 test {ZUNIONSTORE with weights} {
369 list [r zunionstore zsetc 2 zseta zsetb weights 2 3] [r zrange zsetc 0 -1 withscores]
98578b57
PN
370 } {4 {a 2 b 7 d 9 c 12}}
371
bc000c1d
JC
372 test {ZUNIONSTORE with a regular set and weights} {
373 r del seta
374 r sadd seta a
375 r sadd seta b
376 r sadd seta c
377 list [r zunionstore zsetc 2 seta zsetb weights 2 3] [r zrange zsetc 0 -1 withscores]
378 } {4 {a 2 b 5 c 8 d 9}}
379
5d373da9 380 test {ZUNIONSTORE with AGGREGATE MIN} {
381 list [r zunionstore zsetc 2 zseta zsetb aggregate min] [r zrange zsetc 0 -1 withscores]
98578b57
PN
382 } {4 {a 1 b 1 c 2 d 3}}
383
5d373da9 384 test {ZUNIONSTORE with AGGREGATE MAX} {
385 list [r zunionstore zsetc 2 zseta zsetb aggregate max] [r zrange zsetc 0 -1 withscores]
98578b57
PN
386 } {4 {a 1 b 2 c 3 d 3}}
387
5d373da9 388 test {ZINTERSTORE basics} {
389 list [r zinterstore zsetc 2 zseta zsetb] [r zrange zsetc 0 -1 withscores]
98578b57
PN
390 } {2 {b 3 c 5}}
391
5d373da9 392 test {ZINTERSTORE with weights} {
393 list [r zinterstore zsetc 2 zseta zsetb weights 2 3] [r zrange zsetc 0 -1 withscores]
98578b57
PN
394 } {2 {b 7 c 12}}
395
bc000c1d
JC
396 test {ZINTERSTORE with a regular set and weights} {
397 r del seta
398 r sadd seta a
399 r sadd seta b
400 r sadd seta c
401 list [r zinterstore zsetc 2 seta zsetb weights 2 3] [r zrange zsetc 0 -1 withscores]
402 } {2 {b 5 c 8}}
403
5d373da9 404 test {ZINTERSTORE with AGGREGATE MIN} {
405 list [r zinterstore zsetc 2 zseta zsetb aggregate min] [r zrange zsetc 0 -1 withscores]
98578b57
PN
406 } {2 {b 1 c 2}}
407
5d373da9 408 test {ZINTERSTORE with AGGREGATE MAX} {
409 list [r zinterstore zsetc 2 zseta zsetb aggregate max] [r zrange zsetc 0 -1 withscores]
98578b57
PN
410 } {2 {b 2 c 3}}
411
7f7499ee
PN
412 tags {"slow"} {
413 test {ZSETs skiplist implementation backlink consistency test} {
414 set diff 0
415 set elements 10000
416 for {set j 0} {$j < $elements} {incr j} {
417 r zadd myzset [expr rand()] "Element-$j"
418 r zrem myzset "Element-[expr int(rand()*$elements)]"
98578b57 419 }
7f7499ee
PN
420 set l1 [r zrange myzset 0 -1]
421 set l2 [r zrevrange myzset 0 -1]
422 for {set j 0} {$j < [llength $l1]} {incr j} {
423 if {[lindex $l1 $j] ne [lindex $l2 end-$j]} {
424 incr diff
425 }
98578b57 426 }
7f7499ee
PN
427 format $diff
428 } {0}
429
430 test {ZSETs ZRANK augmented skip list stress testing} {
431 set err {}
432 r del myzset
433 for {set k 0} {$k < 10000} {incr k} {
434 set i [expr {$k%1000}]
435 if {[expr rand()] < .2} {
436 r zrem myzset $i
437 } else {
438 set score [expr rand()]
439 r zadd myzset $score $i
440 }
441 set card [r zcard myzset]
442 if {$card > 0} {
443 set index [randomInt $card]
444 set ele [lindex [r zrange myzset $index $index] 0]
445 set rank [r zrank myzset $ele]
446 if {$rank != $index} {
447 set err "$ele RANK is wrong! ($rank != $index)"
448 break
449 }
98578b57
PN
450 }
451 }
7f7499ee
PN
452 set _ $err
453 } {}
454 }
5fc9229c 455
456 test {ZSET element can't be set to nan with ZADD} {
457 set e {}
458 catch {r zadd myzset nan abc} e
459 set _ $e
460 } {*Not A Number*}
461
462 test {ZSET element can't be set to nan with ZINCRBY} {
463 set e {}
464 catch {r zincrby myzset nan abc} e
465 set _ $e
466 } {*Not A Number*}
467
468 test {ZINCRBY calls leading to Nan are refused} {
469 set e {}
470 r zincrby myzset +inf abc
471 catch {r zincrby myzset -inf abc} e
472 set _ $e
473 } {*Not A Number*}
98578b57 474}