1start_server {tags {"dump"}} { 2 test {DUMP / RESTORE are able to serialize / unserialize a simple key} { 3 r set foo bar 4 set encoded [r dump foo] 5 r del foo 6 list [r exists foo] [r restore foo 0 $encoded] [r ttl foo] [r get foo] 7 } {0 OK -1 bar} 8 9 test {RESTORE can set an arbitrary expire to the materialized key} { 10 r set foo bar 11 set encoded [r dump foo] 12 r del foo 13 r restore foo 5000 $encoded 14 set ttl [r pttl foo] 15 assert {$ttl >= 3000 && $ttl <= 5000} 16 r get foo 17 } {bar} 18 19 test {RESTORE can set an expire that overflows a 32 bit integer} { 20 r set foo bar 21 set encoded [r dump foo] 22 r del foo 23 r restore foo 2569591501 $encoded 24 set ttl [r pttl foo] 25 assert {$ttl >= (2569591501-3000) && $ttl <= 2569591501} 26 r get foo 27 } {bar} 28 29 test {RESTORE returns an error of the key already exists} { 30 r set foo bar 31 set e {} 32 catch {r restore foo 0 "..."} e 33 set e 34 } {*BUSYKEY*} 35 36 test {RESTORE can overwrite an existing key with REPLACE} { 37 r set foo bar1 38 set encoded1 [r dump foo] 39 r set foo bar2 40 set encoded2 [r dump foo] 41 r del foo 42 r restore foo 0 $encoded1 43 r restore foo 0 $encoded2 replace 44 r get foo 45 } {bar2} 46 47 test {RESTORE can detect a syntax error for unrecongized options} { 48 catch {r restore foo 0 "..." invalid-option} e 49 set e 50 } {*syntax*} 51 52 test {DUMP of non existing key returns nil} { 53 r dump nonexisting_key 54 } {} 55 56 test {MIGRATE is caching connections} { 57 # Note, we run this as first test so that the connection cache 58 # is empty. 59 set first [srv 0 client] 60 r set key "Some Value" 61 start_server {tags {"repl"}} { 62 set second [srv 0 client] 63 set second_host [srv 0 host] 64 set second_port [srv 0 port] 65 66 assert_match {*migrate_cached_sockets:0*} [r -1 info] 67 r -1 migrate $second_host $second_port key 9 1000 68 assert_match {*migrate_cached_sockets:1*} [r -1 info] 69 } 70 } 71 72 test {MIGRATE cached connections are released after some time} { 73 after 15000 74 assert_match {*migrate_cached_sockets:0*} [r info] 75 } 76 77 test {MIGRATE is able to migrate a key between two instances} { 78 set first [srv 0 client] 79 r set key "Some Value" 80 start_server {tags {"repl"}} { 81 set second [srv 0 client] 82 set second_host [srv 0 host] 83 set second_port [srv 0 port] 84 85 assert {[$first exists key] == 1} 86 assert {[$second exists key] == 0} 87 set ret [r -1 migrate $second_host $second_port key 9 5000] 88 assert {$ret eq {OK}} 89 assert {[$first exists key] == 0} 90 assert {[$second exists key] == 1} 91 assert {[$second get key] eq {Some Value}} 92 assert {[$second ttl key] == -1} 93 } 94 } 95 96 test {MIGRATE is able to copy a key between two instances} { 97 set first [srv 0 client] 98 r del list 99 r lpush list a b c d 100 start_server {tags {"repl"}} { 101 set second [srv 0 client] 102 set second_host [srv 0 host] 103 set second_port [srv 0 port] 104 105 assert {[$first exists list] == 1} 106 assert {[$second exists list] == 0} 107 set ret [r -1 migrate $second_host $second_port list 9 5000 copy] 108 assert {$ret eq {OK}} 109 assert {[$first exists list] == 1} 110 assert {[$second exists list] == 1} 111 assert {[$first lrange list 0 -1] eq [$second lrange list 0 -1]} 112 } 113 } 114 115 test {MIGRATE will not overwrite existing keys, unless REPLACE is used} { 116 set first [srv 0 client] 117 r del list 118 r lpush list a b c d 119 start_server {tags {"repl"}} { 120 set second [srv 0 client] 121 set second_host [srv 0 host] 122 set second_port [srv 0 port] 123 124 assert {[$first exists list] == 1} 125 assert {[$second exists list] == 0} 126 $second set list somevalue 127 catch {r -1 migrate $second_host $second_port list 9 5000 copy} e 128 assert_match {ERR*} $e 129 set res [r -1 migrate $second_host $second_port list 9 5000 copy replace] 130 assert {$ret eq {OK}} 131 assert {[$first exists list] == 1} 132 assert {[$second exists list] == 1} 133 assert {[$first lrange list 0 -1] eq [$second lrange list 0 -1]} 134 } 135 } 136 137 test {MIGRATE propagates TTL correctly} { 138 set first [srv 0 client] 139 r set key "Some Value" 140 start_server {tags {"repl"}} { 141 set second [srv 0 client] 142 set second_host [srv 0 host] 143 set second_port [srv 0 port] 144 145 assert {[$first exists key] == 1} 146 assert {[$second exists key] == 0} 147 $first expire key 10 148 set ret [r -1 migrate $second_host $second_port key 9 5000] 149 assert {$ret eq {OK}} 150 assert {[$first exists key] == 0} 151 assert {[$second exists key] == 1} 152 assert {[$second get key] eq {Some Value}} 153 assert {[$second ttl key] >= 7 && [$second ttl key] <= 10} 154 } 155 } 156 157 test {MIGRATE can correctly transfer large values} { 158 set first [srv 0 client] 159 r del key 160 for {set j 0} {$j < 40000} {incr j} { 161 r rpush key 1 2 3 4 5 6 7 8 9 10 162 r rpush key "item 1" "item 2" "item 3" "item 4" "item 5" \ 163 "item 6" "item 7" "item 8" "item 9" "item 10" 164 } 165 assert {[string length [r dump key]] > (1024*64)} 166 start_server {tags {"repl"}} { 167 set second [srv 0 client] 168 set second_host [srv 0 host] 169 set second_port [srv 0 port] 170 171 assert {[$first exists key] == 1} 172 assert {[$second exists key] == 0} 173 set ret [r -1 migrate $second_host $second_port key 9 10000] 174 assert {$ret eq {OK}} 175 assert {[$first exists key] == 0} 176 assert {[$second exists key] == 1} 177 assert {[$second ttl key] == -1} 178 assert {[$second llen key] == 40000*20} 179 } 180 } 181 182 test {MIGRATE can correctly transfer hashes} { 183 set first [srv 0 client] 184 r del key 185 r hmset key field1 "item 1" field2 "item 2" field3 "item 3" \ 186 field4 "item 4" field5 "item 5" field6 "item 6" 187 start_server {tags {"repl"}} { 188 set second [srv 0 client] 189 set second_host [srv 0 host] 190 set second_port [srv 0 port] 191 192 assert {[$first exists key] == 1} 193 assert {[$second exists key] == 0} 194 set ret [r -1 migrate $second_host $second_port key 9 10000] 195 assert {$ret eq {OK}} 196 assert {[$first exists key] == 0} 197 assert {[$second exists key] == 1} 198 assert {[$second ttl key] == -1} 199 } 200 } 201 202 test {MIGRATE timeout actually works} { 203 set first [srv 0 client] 204 r set key "Some Value" 205 start_server {tags {"repl"}} { 206 set second [srv 0 client] 207 set second_host [srv 0 host] 208 set second_port [srv 0 port] 209 210 assert {[$first exists key] == 1} 211 assert {[$second exists key] == 0} 212 213 set rd [redis_deferring_client] 214 $rd debug sleep 1.0 ; # Make second server unable to reply. 215 set e {} 216 catch {r -1 migrate $second_host $second_port key 9 500} e 217 assert_match {IOERR*} $e 218 } 219 } 220 221 test {MIGRATE can migrate multiple keys at once} { 222 set first [srv 0 client] 223 r set key1 "v1" 224 r set key2 "v2" 225 r set key3 "v3" 226 start_server {tags {"repl"}} { 227 set second [srv 0 client] 228 set second_host [srv 0 host] 229 set second_port [srv 0 port] 230 231 assert {[$first exists key1] == 1} 232 assert {[$second exists key1] == 0} 233 set ret [r -1 migrate $second_host $second_port "" 9 5000 keys key1 key2 key3] 234 assert {$ret eq {OK}} 235 assert {[$first exists key1] == 0} 236 assert {[$first exists key2] == 0} 237 assert {[$first exists key3] == 0} 238 assert {[$second get key1] eq {v1}} 239 assert {[$second get key2] eq {v2}} 240 assert {[$second get key3] eq {v3}} 241 } 242 } 243 244 test {MIGRATE with multiple keys must have empty key arg} { 245 catch {r MIGRATE 127.0.0.1 6379 NotEmpty 9 5000 keys a b c} e 246 set e 247 } {*empty string*} 248 249 test {MIGRATE with mutliple keys migrate just existing ones} { 250 set first [srv 0 client] 251 r set key1 "v1" 252 r set key2 "v2" 253 r set key3 "v3" 254 start_server {tags {"repl"}} { 255 set second [srv 0 client] 256 set second_host [srv 0 host] 257 set second_port [srv 0 port] 258 259 set ret [r -1 migrate $second_host $second_port "" 9 5000 keys nokey-1 nokey-2 nokey-2] 260 assert {$ret eq {NOKEY}} 261 262 assert {[$first exists key1] == 1} 263 assert {[$second exists key1] == 0} 264 set ret [r -1 migrate $second_host $second_port "" 9 5000 keys nokey-1 key1 nokey-2 key2 nokey-3 key3] 265 assert {$ret eq {OK}} 266 assert {[$first exists key1] == 0} 267 assert {[$first exists key2] == 0} 268 assert {[$first exists key3] == 0} 269 assert {[$second get key1] eq {v1}} 270 assert {[$second get key2] eq {v2}} 271 assert {[$second get key3] eq {v3}} 272 } 273 } 274 275 test {MIGRATE with multiple keys: stress command rewriting} { 276 set first [srv 0 client] 277 r flushdb 278 r mset a 1 b 2 c 3 d 4 c 5 e 6 f 7 g 8 h 9 i 10 l 11 m 12 n 13 o 14 p 15 q 16 279 start_server {tags {"repl"}} { 280 set second [srv 0 client] 281 set second_host [srv 0 host] 282 set second_port [srv 0 port] 283 284 set ret [r -1 migrate $second_host $second_port "" 9 5000 keys a b c d e f g h i l m n o p q] 285 286 assert {[$first dbsize] == 0} 287 assert {[$second dbsize] == 15} 288 } 289 } 290 291 test {MIGRATE with multiple keys: delete just ack keys} { 292 set first [srv 0 client] 293 r flushdb 294 r mset a 1 b 2 c 3 d 4 c 5 e 6 f 7 g 8 h 9 i 10 l 11 m 12 n 13 o 14 p 15 q 16 295 start_server {tags {"repl"}} { 296 set second [srv 0 client] 297 set second_host [srv 0 host] 298 set second_port [srv 0 port] 299 300 $second mset c _ d _; # Two busy keys and no REPLACE used 301 302 catch {r -1 migrate $second_host $second_port "" 9 5000 keys a b c d e f g h i l m n o p q} e 303 304 assert {[$first dbsize] == 2} 305 assert {[$second dbsize] == 15} 306 assert {[$first exists c] == 1} 307 assert {[$first exists d] == 1} 308 } 309 } 310 311} 312