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