1
0

dump.tcl 13 KB

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