]> git.saurik.com Git - redis.git/blob - tests/unit/type/set.tcl
c4fd4d7677154bb3ae504648824b333e2c0b6abf
[redis.git] / tests / unit / type / set.tcl
1 start_server {tags {"set"}} {
2 proc create_set {key entries} {
3 r del $key
4 foreach entry $entries { r sadd $key $entry }
5 }
6
7 test {SADD, SCARD, SISMEMBER, SMEMBERS basics - regular set} {
8 create_set myset {foo}
9 assert_encoding hashtable myset
10 assert_equal 1 [r sadd myset bar]
11 assert_equal 0 [r sadd myset bar]
12 assert_equal 2 [r scard myset]
13 assert_equal 1 [r sismember myset foo]
14 assert_equal 1 [r sismember myset bar]
15 assert_equal 0 [r sismember myset bla]
16 assert_equal {bar foo} [lsort [r smembers myset]]
17 }
18
19 test {SADD, SCARD, SISMEMBER, SMEMBERS basics - intset} {
20 create_set myset {17}
21 assert_encoding intset myset
22 assert_equal 1 [r sadd myset 16]
23 assert_equal 0 [r sadd myset 16]
24 assert_equal 2 [r scard myset]
25 assert_equal 1 [r sismember myset 16]
26 assert_equal 1 [r sismember myset 17]
27 assert_equal 0 [r sismember myset 18]
28 assert_equal {16 17} [lsort [r smembers myset]]
29 }
30
31 test {SADD against non set} {
32 r lpush mylist foo
33 assert_error ERR*kind* {r sadd mylist bar}
34 }
35
36 test {SREM basics - regular set} {
37 create_set myset {foo bar ciao}
38 assert_encoding hashtable myset
39 assert_equal 0 [r srem myset qux]
40 assert_equal 1 [r srem myset foo]
41 assert_equal {bar ciao} [lsort [r smembers myset]]
42 }
43
44 test {SREM basics - intset} {
45 create_set myset {3 4 5}
46 assert_encoding intset myset
47 assert_equal 0 [r srem myset 6]
48 assert_equal 1 [r srem myset 4]
49 assert_equal {3 5} [lsort [r smembers myset]]
50 }
51
52 foreach {type} {hashtable intset} {
53 for {set i 1} {$i <= 5} {incr i} {
54 r del [format "set%d" $i]
55 }
56 for {set i 0} {$i < 1000} {incr i} {
57 r sadd set1 $i
58 r sadd set2 [expr $i+995]
59 }
60 foreach i {999 995 1000 2000} {
61 r sadd set3 $i
62 }
63 for {set i 5} {$i < 1000} {incr i} {
64 r sadd set4 $i
65 }
66 r sadd set5 0
67
68 # it is possible that a hashtable encoded only contains integers,
69 # because it is converted from an intset to a hashtable when a
70 # non-integer element is added and then removed.
71 if {$type eq "hashtable"} {
72 for {set i 1} {$i <= 5} {incr i} {
73 r sadd [format "set%d" $i] foo
74 r srem [format "set%d" $i] foo
75 }
76 }
77
78 test "Generated sets must be encoded as $type" {
79 for {set i 1} {$i <= 5} {incr i} {
80 assert_encoding $type [format "set%d" $i]
81 }
82 }
83
84 test "SINTER with two sets - $type" {
85 assert_equal {995 996 997 998 999} [lsort [r sinter set1 set2]]
86 }
87
88 test "SINTERSTORE with two sets - $type" {
89 r sinterstore setres set1 set2
90 assert_encoding intset setres
91 assert_equal {995 996 997 998 999} [lsort [r smembers setres]]
92 }
93
94 test "SINTERSTORE with two sets, after a DEBUG RELOAD - $type" {
95 r debug reload
96 r sinterstore setres set1 set2
97 assert_encoding intset setres
98 assert_equal {995 996 997 998 999} [lsort [r smembers setres]]
99 }
100
101 test "SUNION with two sets - $type" {
102 set expected [lsort -uniq "[r smembers set1] [r smembers set2]"]
103 assert_equal $expected [lsort [r sunion set1 set2]]
104 }
105
106 test "SUNIONSTORE with two sets - $type" {
107 r sunionstore setres set1 set2
108 assert_encoding intset setres
109 set expected [lsort -uniq "[r smembers set1] [r smembers set2]"]
110 assert_equal $expected [lsort [r smembers setres]]
111 }
112
113 test "SINTER against three sets - $type" {
114 assert_equal {995 999} [lsort [r sinter set1 set2 set3]]
115 }
116
117 test "SINTERSTORE with three sets - $type" {
118 r sinterstore setres set1 set2 set3
119 assert_equal {995 999} [r smembers setres]
120 }
121
122 test "SUNION with non existing keys - $type" {
123 set expected [lsort -uniq "[r smembers set1] [r smembers set2]"]
124 assert_equal $expected [lsort [r sunion nokey1 set1 set2 nokey2]]
125 }
126
127 test "SDIFF with two sets - $type" {
128 assert_equal {0 1 2 3 4} [lsort [r sdiff set1 set4]]
129 }
130
131 test "SDIFF with three sets - $type" {
132 assert_equal {1 2 3 4} [lsort [r sdiff set1 set4 set5]]
133 }
134
135 test "SDIFFSTORE with three sets - $type" {
136 r sdiffstore setres set1 set4 set5
137 assert_encoding intset setres
138 assert_equal {1 2 3 4} [lsort [r smembers setres]]
139 }
140 }
141
142 test "SINTER against non-set should throw error" {
143 r set key1 x
144 assert_error "ERR*wrong kind*" {r sinter key1 noset}
145 }
146
147 test "SUNION against non-set should throw error" {
148 r set key1 x
149 assert_error "ERR*wrong kind*" {r sunion key1 noset}
150 }
151
152 test "SINTERSTORE against non existing keys should delete dstkey" {
153 r set setres xxx
154 assert_equal 0 [r sinterstore setres foo111 bar222]
155 assert_equal 0 [r exists setres]
156 }
157
158 test "SUNIONSTORE against non existing keys should delete dstkey" {
159 r set setres xxx
160 assert_equal 0 [r sunionstore setres foo111 bar222]
161 assert_equal 0 [r exists setres]
162 }
163
164 foreach {type contents} {hashtable {a b c} intset {1 2 3}} {
165 test "SPOP basics - $type" {
166 create_set myset $contents
167 assert_encoding $type myset
168 assert_equal $contents [lsort [list [r spop myset] [r spop myset] [r spop myset]]]
169 assert_equal 0 [r scard myset]
170 }
171
172 test "SRANDMEMBER - $type" {
173 create_set myset $contents
174 unset -nocomplain myset
175 array set myset {}
176 for {set i 0} {$i < 100} {incr i} {
177 set myset([r srandmember myset]) 1
178 }
179 assert_equal $contents [lsort [array names myset]]
180 }
181 }
182
183 test {SMOVE basics} {
184 r sadd myset1 a
185 r sadd myset1 b
186 r sadd myset1 c
187 r sadd myset2 x
188 r sadd myset2 y
189 r sadd myset2 z
190 r smove myset1 myset2 a
191 list [lsort [r smembers myset2]] [lsort [r smembers myset1]]
192 } {{a x y z} {b c}}
193
194 test {SMOVE non existing key} {
195 list [r smove myset1 myset2 foo] [lsort [r smembers myset2]] [lsort [r smembers myset1]]
196 } {0 {a x y z} {b c}}
197
198 test {SMOVE non existing src set} {
199 list [r smove noset myset2 foo] [lsort [r smembers myset2]]
200 } {0 {a x y z}}
201
202 test {SMOVE non existing dst set} {
203 list [r smove myset2 myset3 y] [lsort [r smembers myset2]] [lsort [r smembers myset3]]
204 } {1 {a x z} y}
205
206 test {SMOVE wrong src key type} {
207 r set x 10
208 catch {r smove x myset2 foo} err
209 format $err
210 } {ERR*}
211
212 test {SMOVE wrong dst key type} {
213 r set x 10
214 catch {r smove myset2 x foo} err
215 format $err
216 } {ERR*}
217 }