xref: /redis-3.2.3/tests/unit/dump.tcl (revision f99be541)
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