xref: /f-stack/app/redis-5.0.5/tests/unit/dump.tcl (revision 572c4311)
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 can set an absolute expire} {
30        r set foo bar
31        set encoded [r dump foo]
32        r del foo
33        set now [clock milliseconds]
34        r restore foo [expr $now+3000] $encoded absttl
35        set ttl [r pttl foo]
36        assert {$ttl >= 2900 && $ttl <= 3100}
37        r get foo
38    } {bar}
39
40    test {RESTORE can set LRU} {
41        r set foo bar
42        set encoded [r dump foo]
43        r del foo
44        r config set maxmemory-policy allkeys-lru
45        r restore foo 0 $encoded idletime 1000
46        set idle [r object idletime foo]
47        assert {$idle >= 1000 && $idle <= 1010}
48        r get foo
49    } {bar}
50
51    test {RESTORE can set LFU} {
52        r set foo bar
53        set encoded [r dump foo]
54        r del foo
55        r config set maxmemory-policy allkeys-lfu
56        r restore foo 0 $encoded freq 100
57        set freq [r object freq foo]
58        assert {$freq == 100}
59        r get foo
60    } {bar}
61
62    test {RESTORE returns an error of the key already exists} {
63        r set foo bar
64        set e {}
65        catch {r restore foo 0 "..."} e
66        set e
67    } {*BUSYKEY*}
68
69    test {RESTORE can overwrite an existing key with REPLACE} {
70        r set foo bar1
71        set encoded1 [r dump foo]
72        r set foo bar2
73        set encoded2 [r dump foo]
74        r del foo
75        r restore foo 0 $encoded1
76        r restore foo 0 $encoded2 replace
77        r get foo
78    } {bar2}
79
80    test {RESTORE can detect a syntax error for unrecongized options} {
81        catch {r restore foo 0 "..." invalid-option} e
82        set e
83    } {*syntax*}
84
85    test {DUMP of non existing key returns nil} {
86        r dump nonexisting_key
87    } {}
88
89    test {MIGRATE is caching connections} {
90        # Note, we run this as first test so that the connection cache
91        # is empty.
92        set first [srv 0 client]
93        r set key "Some Value"
94        start_server {tags {"repl"}} {
95            set second [srv 0 client]
96            set second_host [srv 0 host]
97            set second_port [srv 0 port]
98
99            assert_match {*migrate_cached_sockets:0*} [r -1 info]
100            r -1 migrate $second_host $second_port key 9 1000
101            assert_match {*migrate_cached_sockets:1*} [r -1 info]
102        }
103    }
104
105    test {MIGRATE cached connections are released after some time} {
106        after 15000
107        assert_match {*migrate_cached_sockets:0*} [r info]
108    }
109
110    test {MIGRATE is able to migrate a key between two instances} {
111        set first [srv 0 client]
112        r set key "Some Value"
113        start_server {tags {"repl"}} {
114            set second [srv 0 client]
115            set second_host [srv 0 host]
116            set second_port [srv 0 port]
117
118            assert {[$first exists key] == 1}
119            assert {[$second exists key] == 0}
120            set ret [r -1 migrate $second_host $second_port key 9 5000]
121            assert {$ret eq {OK}}
122            assert {[$first exists key] == 0}
123            assert {[$second exists key] == 1}
124            assert {[$second get key] eq {Some Value}}
125            assert {[$second ttl key] == -1}
126        }
127    }
128
129    test {MIGRATE is able to copy a key between two instances} {
130        set first [srv 0 client]
131        r del list
132        r lpush list a b c d
133        start_server {tags {"repl"}} {
134            set second [srv 0 client]
135            set second_host [srv 0 host]
136            set second_port [srv 0 port]
137
138            assert {[$first exists list] == 1}
139            assert {[$second exists list] == 0}
140            set ret [r -1 migrate $second_host $second_port list 9 5000 copy]
141            assert {$ret eq {OK}}
142            assert {[$first exists list] == 1}
143            assert {[$second exists list] == 1}
144            assert {[$first lrange list 0 -1] eq [$second lrange list 0 -1]}
145        }
146    }
147
148    test {MIGRATE will not overwrite existing keys, unless REPLACE is used} {
149        set first [srv 0 client]
150        r del list
151        r lpush list a b c d
152        start_server {tags {"repl"}} {
153            set second [srv 0 client]
154            set second_host [srv 0 host]
155            set second_port [srv 0 port]
156
157            assert {[$first exists list] == 1}
158            assert {[$second exists list] == 0}
159            $second set list somevalue
160            catch {r -1 migrate $second_host $second_port list 9 5000 copy} e
161            assert_match {ERR*} $e
162            set res [r -1 migrate $second_host $second_port list 9 5000 copy replace]
163            assert {$ret eq {OK}}
164            assert {[$first exists list] == 1}
165            assert {[$second exists list] == 1}
166            assert {[$first lrange list 0 -1] eq [$second lrange list 0 -1]}
167        }
168    }
169
170    test {MIGRATE propagates TTL correctly} {
171        set first [srv 0 client]
172        r set key "Some Value"
173        start_server {tags {"repl"}} {
174            set second [srv 0 client]
175            set second_host [srv 0 host]
176            set second_port [srv 0 port]
177
178            assert {[$first exists key] == 1}
179            assert {[$second exists key] == 0}
180            $first expire key 10
181            set ret [r -1 migrate $second_host $second_port key 9 5000]
182            assert {$ret eq {OK}}
183            assert {[$first exists key] == 0}
184            assert {[$second exists key] == 1}
185            assert {[$second get key] eq {Some Value}}
186            assert {[$second ttl key] >= 7 && [$second ttl key] <= 10}
187        }
188    }
189
190    test {MIGRATE can correctly transfer large values} {
191        set first [srv 0 client]
192        r del key
193        for {set j 0} {$j < 40000} {incr j} {
194            r rpush key 1 2 3 4 5 6 7 8 9 10
195            r rpush key "item 1" "item 2" "item 3" "item 4" "item 5" \
196                        "item 6" "item 7" "item 8" "item 9" "item 10"
197        }
198        assert {[string length [r dump key]] > (1024*64)}
199        start_server {tags {"repl"}} {
200            set second [srv 0 client]
201            set second_host [srv 0 host]
202            set second_port [srv 0 port]
203
204            assert {[$first exists key] == 1}
205            assert {[$second exists key] == 0}
206            set ret [r -1 migrate $second_host $second_port key 9 10000]
207            assert {$ret eq {OK}}
208            assert {[$first exists key] == 0}
209            assert {[$second exists key] == 1}
210            assert {[$second ttl key] == -1}
211            assert {[$second llen key] == 40000*20}
212        }
213    }
214
215    test {MIGRATE can correctly transfer hashes} {
216        set first [srv 0 client]
217        r del key
218        r hmset key field1 "item 1" field2 "item 2" field3 "item 3" \
219                    field4 "item 4" field5 "item 5" field6 "item 6"
220        start_server {tags {"repl"}} {
221            set second [srv 0 client]
222            set second_host [srv 0 host]
223            set second_port [srv 0 port]
224
225            assert {[$first exists key] == 1}
226            assert {[$second exists key] == 0}
227            set ret [r -1 migrate $second_host $second_port key 9 10000]
228            assert {$ret eq {OK}}
229            assert {[$first exists key] == 0}
230            assert {[$second exists key] == 1}
231            assert {[$second ttl key] == -1}
232        }
233    }
234
235    test {MIGRATE timeout actually works} {
236        set first [srv 0 client]
237        r set key "Some Value"
238        start_server {tags {"repl"}} {
239            set second [srv 0 client]
240            set second_host [srv 0 host]
241            set second_port [srv 0 port]
242
243            assert {[$first exists key] == 1}
244            assert {[$second exists key] == 0}
245
246            set rd [redis_deferring_client]
247            $rd debug sleep 1.0 ; # Make second server unable to reply.
248            set e {}
249            catch {r -1 migrate $second_host $second_port key 9 500} e
250            assert_match {IOERR*} $e
251        }
252    }
253
254    test {MIGRATE can migrate multiple keys at once} {
255        set first [srv 0 client]
256        r set key1 "v1"
257        r set key2 "v2"
258        r set key3 "v3"
259        start_server {tags {"repl"}} {
260            set second [srv 0 client]
261            set second_host [srv 0 host]
262            set second_port [srv 0 port]
263
264            assert {[$first exists key1] == 1}
265            assert {[$second exists key1] == 0}
266            set ret [r -1 migrate $second_host $second_port "" 9 5000 keys key1 key2 key3]
267            assert {$ret eq {OK}}
268            assert {[$first exists key1] == 0}
269            assert {[$first exists key2] == 0}
270            assert {[$first exists key3] == 0}
271            assert {[$second get key1] eq {v1}}
272            assert {[$second get key2] eq {v2}}
273            assert {[$second get key3] eq {v3}}
274        }
275    }
276
277    test {MIGRATE with multiple keys must have empty key arg} {
278        catch {r MIGRATE 127.0.0.1 6379 NotEmpty 9 5000 keys a b c} e
279        set e
280    } {*empty string*}
281
282    test {MIGRATE with multiple keys migrate just existing ones} {
283        set first [srv 0 client]
284        r set key1 "v1"
285        r set key2 "v2"
286        r set key3 "v3"
287        start_server {tags {"repl"}} {
288            set second [srv 0 client]
289            set second_host [srv 0 host]
290            set second_port [srv 0 port]
291
292            set ret [r -1 migrate $second_host $second_port "" 9 5000 keys nokey-1 nokey-2 nokey-2]
293            assert {$ret eq {NOKEY}}
294
295            assert {[$first exists key1] == 1}
296            assert {[$second exists key1] == 0}
297            set ret [r -1 migrate $second_host $second_port "" 9 5000 keys nokey-1 key1 nokey-2 key2 nokey-3 key3]
298            assert {$ret eq {OK}}
299            assert {[$first exists key1] == 0}
300            assert {[$first exists key2] == 0}
301            assert {[$first exists key3] == 0}
302            assert {[$second get key1] eq {v1}}
303            assert {[$second get key2] eq {v2}}
304            assert {[$second get key3] eq {v3}}
305        }
306    }
307
308    test {MIGRATE with multiple keys: stress command rewriting} {
309        set first [srv 0 client]
310        r flushdb
311        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
312        start_server {tags {"repl"}} {
313            set second [srv 0 client]
314            set second_host [srv 0 host]
315            set second_port [srv 0 port]
316
317            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]
318
319            assert {[$first dbsize] == 0}
320            assert {[$second dbsize] == 15}
321        }
322    }
323
324    test {MIGRATE with multiple keys: delete just ack keys} {
325        set first [srv 0 client]
326        r flushdb
327        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
328        start_server {tags {"repl"}} {
329            set second [srv 0 client]
330            set second_host [srv 0 host]
331            set second_port [srv 0 port]
332
333            $second mset c _ d _; # Two busy keys and no REPLACE used
334
335            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
336
337            assert {[$first dbsize] == 2}
338            assert {[$second dbsize] == 15}
339            assert {[$first exists c] == 1}
340            assert {[$first exists d] == 1}
341        }
342    }
343
344    test {MIGRATE AUTH: correct and wrong password cases} {
345        set first [srv 0 client]
346        r del list
347        r lpush list a b c d
348        start_server {tags {"repl"}} {
349            set second [srv 0 client]
350            set second_host [srv 0 host]
351            set second_port [srv 0 port]
352            $second config set requirepass foobar
353            $second auth foobar
354
355            assert {[$first exists list] == 1}
356            assert {[$second exists list] == 0}
357            set ret [r -1 migrate $second_host $second_port list 9 5000 AUTH foobar]
358            assert {$ret eq {OK}}
359            assert {[$second exists list] == 1}
360            assert {[$second lrange list 0 -1] eq {d c b a}}
361
362            r -1 lpush list a b c d
363            $second config set requirepass foobar2
364            catch {r -1 migrate $second_host $second_port list 9 5000 AUTH foobar} err
365            assert_match {*invalid password*} $err
366        }
367    }
368}
369