]>
Commit | Line | Data |
---|---|---|
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 | } |