aboutsummaryrefslogtreecommitdiff
path: root/examples/redis-unstable/tests/unit/bitfield.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/tests/unit/bitfield.tcl')
-rw-r--r--examples/redis-unstable/tests/unit/bitfield.tcl263
1 files changed, 263 insertions, 0 deletions
diff --git a/examples/redis-unstable/tests/unit/bitfield.tcl b/examples/redis-unstable/tests/unit/bitfield.tcl
new file mode 100644
index 0000000..21091aa
--- /dev/null
+++ b/examples/redis-unstable/tests/unit/bitfield.tcl
@@ -0,0 +1,263 @@
1start_server {tags {"bitops"}} {
2 test {BITFIELD signed SET and GET basics} {
3 r del bits
4 set results {}
5 lappend results [r bitfield bits set i8 0 -100]
6 lappend results [r bitfield bits set i8 0 101]
7 lappend results [r bitfield bits get i8 0]
8 set results
9 } {0 -100 101}
10
11 test {BITFIELD unsigned SET and GET basics} {
12 r del bits
13 set results {}
14 lappend results [r bitfield bits set u8 0 255]
15 lappend results [r bitfield bits set u8 0 100]
16 lappend results [r bitfield bits get u8 0]
17 set results
18 } {0 255 100}
19
20 test {BITFIELD signed SET and GET together} {
21 r del bits
22 set results [r bitfield bits set i8 0 255 set i8 0 100 get i8 0]
23 } {0 -1 100}
24
25 test {BITFIELD unsigned with SET, GET and INCRBY arguments} {
26 r del bits
27 set results [r bitfield bits set u8 0 255 incrby u8 0 100 get u8 0]
28 } {0 99 99}
29
30 test {BITFIELD with only key as argument} {
31 r del bits
32 set result [r bitfield bits]
33 assert {$result eq {}}
34 }
35
36 test {BITFIELD #<idx> form} {
37 r del bits
38 set results {}
39 r bitfield bits set u8 #0 65
40 r bitfield bits set u8 #1 66
41 r bitfield bits set u8 #2 67
42 r get bits
43 } {ABC}
44
45 test {BITFIELD basic INCRBY form} {
46 r del bits
47 set results {}
48 r bitfield bits set u8 #0 10
49 lappend results [r bitfield bits incrby u8 #0 100]
50 lappend results [r bitfield bits incrby u8 #0 100]
51 set results
52 } {110 210}
53
54 test {BITFIELD chaining of multiple commands} {
55 r del bits
56 set results {}
57 r bitfield bits set u8 #0 10
58 lappend results [r bitfield bits incrby u8 #0 100 incrby u8 #0 100]
59 set results
60 } {{110 210}}
61
62 test {BITFIELD unsigned overflow wrap} {
63 r del bits
64 set results {}
65 r bitfield bits set u8 #0 100
66 lappend results [r bitfield bits overflow wrap incrby u8 #0 257]
67 lappend results [r bitfield bits get u8 #0]
68 lappend results [r bitfield bits overflow wrap incrby u8 #0 255]
69 lappend results [r bitfield bits get u8 #0]
70 } {101 101 100 100}
71
72 test {BITFIELD unsigned overflow sat} {
73 r del bits
74 set results {}
75 r bitfield bits set u8 #0 100
76 lappend results [r bitfield bits overflow sat incrby u8 #0 257]
77 lappend results [r bitfield bits get u8 #0]
78 lappend results [r bitfield bits overflow sat incrby u8 #0 -255]
79 lappend results [r bitfield bits get u8 #0]
80 } {255 255 0 0}
81
82 test {BITFIELD signed overflow wrap} {
83 r del bits
84 set results {}
85 r bitfield bits set i8 #0 100
86 lappend results [r bitfield bits overflow wrap incrby i8 #0 257]
87 lappend results [r bitfield bits get i8 #0]
88 lappend results [r bitfield bits overflow wrap incrby i8 #0 255]
89 lappend results [r bitfield bits get i8 #0]
90 } {101 101 100 100}
91
92 test {BITFIELD signed overflow sat} {
93 r del bits
94 set results {}
95 r bitfield bits set u8 #0 100
96 lappend results [r bitfield bits overflow sat incrby i8 #0 257]
97 lappend results [r bitfield bits get i8 #0]
98 lappend results [r bitfield bits overflow sat incrby i8 #0 -255]
99 lappend results [r bitfield bits get i8 #0]
100 } {127 127 -128 -128}
101
102 test {BITFIELD overflow detection fuzzing} {
103 for {set j 0} {$j < 1000} {incr j} {
104 set bits [expr {[randomInt 64]+1}]
105 set sign [randomInt 2]
106 set range [expr {2**$bits}]
107 if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
108 if {$sign} {
109 set min [expr {-($range/2)}]
110 set type "i$bits"
111 } else {
112 set min 0
113 set type "u$bits"
114 }
115 set max [expr {$min+$range-1}]
116
117 # Compare Tcl vs Redis
118 set range2 [expr {$range*2}]
119 set value [expr {($min*2)+[randomInt $range2]}]
120 set increment [expr {($min*2)+[randomInt $range2]}]
121 if {$value > 9223372036854775807} {
122 set value 9223372036854775807
123 }
124 if {$value < -9223372036854775808} {
125 set value -9223372036854775808
126 }
127 if {$increment > 9223372036854775807} {
128 set increment 9223372036854775807
129 }
130 if {$increment < -9223372036854775808} {
131 set increment -9223372036854775808
132 }
133
134 set overflow 0
135 if {$value > $max || $value < $min} {set overflow 1}
136 if {($value + $increment) > $max} {set overflow 1}
137 if {($value + $increment) < $min} {set overflow 1}
138
139 r del bits
140 set res1 [r bitfield bits overflow fail set $type 0 $value]
141 set res2 [r bitfield bits overflow fail incrby $type 0 $increment]
142
143 if {$overflow && [lindex $res1 0] ne {} &&
144 [lindex $res2 0] ne {}} {
145 fail "OW not detected where needed: $type $value+$increment"
146 }
147 if {!$overflow && ([lindex $res1 0] eq {} ||
148 [lindex $res2 0] eq {})} {
149 fail "OW detected where NOT needed: $type $value+$increment"
150 }
151 }
152 }
153
154 test {BITFIELD overflow wrap fuzzing} {
155 for {set j 0} {$j < 1000} {incr j} {
156 set bits [expr {[randomInt 64]+1}]
157 set sign [randomInt 2]
158 set range [expr {2**$bits}]
159 if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
160 if {$sign} {
161 set min [expr {-($range/2)}]
162 set type "i$bits"
163 } else {
164 set min 0
165 set type "u$bits"
166 }
167 set max [expr {$min+$range-1}]
168
169 # Compare Tcl vs Redis
170 set range2 [expr {$range*2}]
171 set value [expr {($min*2)+[randomInt $range2]}]
172 set increment [expr {($min*2)+[randomInt $range2]}]
173 if {$value > 9223372036854775807} {
174 set value 9223372036854775807
175 }
176 if {$value < -9223372036854775808} {
177 set value -9223372036854775808
178 }
179 if {$increment > 9223372036854775807} {
180 set increment 9223372036854775807
181 }
182 if {$increment < -9223372036854775808} {
183 set increment -9223372036854775808
184 }
185
186 r del bits
187 r bitfield bits overflow wrap set $type 0 $value
188 r bitfield bits overflow wrap incrby $type 0 $increment
189 set res [lindex [r bitfield bits get $type 0] 0]
190
191 set expected 0
192 if {$sign} {incr expected [expr {$max+1}]}
193 incr expected $value
194 incr expected $increment
195 set expected [expr {$expected % $range}]
196 if {$sign} {incr expected $min}
197
198 if {$res != $expected} {
199 fail "WRAP error: $type $value+$increment = $res, should be $expected"
200 }
201 }
202 }
203
204 test {BITFIELD regression for #3221} {
205 r set bits 1
206 r bitfield bits get u1 0
207 } {0}
208
209 test {BITFIELD regression for #3564} {
210 for {set j 0} {$j < 10} {incr j} {
211 r del mystring
212 set res [r BITFIELD mystring SET i8 0 10 SET i8 64 10 INCRBY i8 10 99900]
213 assert {$res eq {0 0 60}}
214 }
215 r del mystring
216 }
217
218 test {BITFIELD_RO with only key as argument} {
219 set res [r bitfield_ro bits]
220 assert {$res eq {}}
221 }
222
223 test {BITFIELD_RO fails when write option is used} {
224 catch {r bitfield_ro bits set u8 0 100 get u8 0} err
225 assert_match {*ERR BITFIELD_RO only supports the GET subcommand*} $err
226 }
227}
228
229start_server {tags {"repl external:skip"}} {
230 start_server {} {
231 set master [srv -1 client]
232 set master_host [srv -1 host]
233 set master_port [srv -1 port]
234 set slave [srv 0 client]
235
236 test {BITFIELD: setup slave} {
237 $slave slaveof $master_host $master_port
238 wait_for_condition 50 100 {
239 [s 0 master_link_status] eq {up}
240 } else {
241 fail "Replication not started."
242 }
243 }
244
245 test {BITFIELD: write on master, read on slave} {
246 $master del bits
247 assert_equal 0 [$master bitfield bits set u8 0 255]
248 assert_equal 255 [$master bitfield bits set u8 0 100]
249 wait_for_ofs_sync $master $slave
250 assert_equal 100 [$slave bitfield_ro bits get u8 0]
251 }
252
253 test {BITFIELD_RO with only key as argument on read-only replica} {
254 set res [$slave bitfield_ro bits]
255 assert {$res eq {}}
256 }
257
258 test {BITFIELD_RO fails when write option is used on read-only replica} {
259 catch {$slave bitfield_ro bits set u8 0 100 get u8 0} err
260 assert_match {*ERR BITFIELD_RO only supports the GET subcommand*} $err
261 }
262 }
263}