basic.tcl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. start_server {tags {"basic"}} {
  2. test {DEL all keys to start with a clean DB} {
  3. foreach key [r keys *] {r del $key}
  4. r dbsize
  5. } {0}
  6. test {SET and GET an item} {
  7. r set x foobar
  8. r get x
  9. } {foobar}
  10. test {SET and GET an empty item} {
  11. r set x {}
  12. r get x
  13. } {}
  14. test {DEL against a single item} {
  15. r del x
  16. r get x
  17. } {}
  18. test {Vararg DEL} {
  19. r set foo1 a
  20. r set foo2 b
  21. r set foo3 c
  22. list [r del foo1 foo2 foo3 foo4] [r mget foo1 foo2 foo3]
  23. } {3 {{} {} {}}}
  24. test {KEYS with pattern} {
  25. foreach key {key_x key_y key_z foo_a foo_b foo_c} {
  26. r set $key hello
  27. }
  28. lsort [r keys foo*]
  29. } {foo_a foo_b foo_c}
  30. test {KEYS to get all keys} {
  31. lsort [r keys *]
  32. } {foo_a foo_b foo_c key_x key_y key_z}
  33. test {DBSIZE} {
  34. r dbsize
  35. } {6}
  36. test {DEL all keys} {
  37. foreach key [r keys *] {r del $key}
  38. r dbsize
  39. } {0}
  40. test {Very big payload in GET/SET} {
  41. set buf [string repeat "abcd" 1000000]
  42. r set foo $buf
  43. r get foo
  44. } [string repeat "abcd" 1000000]
  45. tags {"slow"} {
  46. test {Very big payload random access} {
  47. set err {}
  48. array set payload {}
  49. for {set j 0} {$j < 100} {incr j} {
  50. set size [expr 1+[randomInt 100000]]
  51. set buf [string repeat "pl-$j" $size]
  52. set payload($j) $buf
  53. r set bigpayload_$j $buf
  54. }
  55. for {set j 0} {$j < 1000} {incr j} {
  56. set index [randomInt 100]
  57. set buf [r get bigpayload_$index]
  58. if {$buf != $payload($index)} {
  59. set err "Values differ: I set '$payload($index)' but I read back '$buf'"
  60. break
  61. }
  62. }
  63. unset payload
  64. set _ $err
  65. } {}
  66. test {SET 10000 numeric keys and access all them in reverse order} {
  67. set err {}
  68. for {set x 0} {$x < 10000} {incr x} {
  69. r set $x $x
  70. }
  71. set sum 0
  72. for {set x 9999} {$x >= 0} {incr x -1} {
  73. set val [r get $x]
  74. if {$val ne $x} {
  75. set err "Eleemnt at position $x is $val instead of $x"
  76. break
  77. }
  78. }
  79. set _ $err
  80. } {}
  81. test {DBSIZE should be 10101 now} {
  82. r dbsize
  83. } {10101}
  84. }
  85. test {INCR against non existing key} {
  86. set res {}
  87. append res [r incr novar]
  88. append res [r get novar]
  89. } {11}
  90. test {INCR against key created by incr itself} {
  91. r incr novar
  92. } {2}
  93. test {INCR against key originally set with SET} {
  94. r set novar 100
  95. r incr novar
  96. } {101}
  97. test {INCR over 32bit value} {
  98. r set novar 17179869184
  99. r incr novar
  100. } {17179869185}
  101. test {INCRBY over 32bit value with over 32bit increment} {
  102. r set novar 17179869184
  103. r incrby novar 17179869184
  104. } {34359738368}
  105. test {INCR fails against key with spaces (no integer encoded)} {
  106. r set novar " 11 "
  107. catch {r incr novar} err
  108. format $err
  109. } {ERR*}
  110. test {INCR fails against a key holding a list} {
  111. r rpush mylist 1
  112. catch {r incr mylist} err
  113. r rpop mylist
  114. format $err
  115. } {ERR*}
  116. test {DECRBY over 32bit value with over 32bit increment, negative res} {
  117. r set novar 17179869184
  118. r decrby novar 17179869185
  119. } {-1}
  120. test "SETNX target key missing" {
  121. r del novar
  122. assert_equal 1 [r setnx novar foobared]
  123. assert_equal "foobared" [r get novar]
  124. }
  125. test "SETNX target key exists" {
  126. r set novar foobared
  127. assert_equal 0 [r setnx novar blabla]
  128. assert_equal "foobared" [r get novar]
  129. }
  130. test "SETNX against not-expired volatile key" {
  131. r set x 10
  132. r expire x 10000
  133. assert_equal 0 [r setnx x 20]
  134. assert_equal 10 [r get x]
  135. }
  136. test "SETNX against expired volatile key" {
  137. # Make it very unlikely for the key this test uses to be expired by the
  138. # active expiry cycle. This is tightly coupled to the implementation of
  139. # active expiry and dbAdd() but currently the only way to test that
  140. # SETNX expires a key when it should have been.
  141. for {set x 0} {$x < 9999} {incr x} {
  142. r setex key-$x 3600 value
  143. }
  144. # This will be one of 10000 expiring keys. A cycle is executed every
  145. # 100ms, sampling 10 keys for being expired or not. This key will be
  146. # expired for at most 1s when we wait 2s, resulting in a total sample
  147. # of 100 keys. The probability of the success of this test being a
  148. # false positive is therefore approx. 1%.
  149. r set x 10
  150. r expire x 1
  151. # Wait for the key to expire
  152. after 2000
  153. assert_equal 1 [r setnx x 20]
  154. assert_equal 20 [r get x]
  155. }
  156. test {EXISTS} {
  157. set res {}
  158. r set newkey test
  159. append res [r exists newkey]
  160. r del newkey
  161. append res [r exists newkey]
  162. } {10}
  163. test {Zero length value in key. SET/GET/EXISTS} {
  164. r set emptykey {}
  165. set res [r get emptykey]
  166. append res [r exists emptykey]
  167. r del emptykey
  168. append res [r exists emptykey]
  169. } {10}
  170. test {Commands pipelining} {
  171. set fd [r channel]
  172. puts -nonewline $fd "SET k1 xyzk\r\nGET k1\r\nPING\r\n"
  173. flush $fd
  174. set res {}
  175. append res [string match OK* [::redis::redis_read_reply $fd]]
  176. append res [::redis::redis_read_reply $fd]
  177. append res [string match PONG* [::redis::redis_read_reply $fd]]
  178. format $res
  179. } {1xyzk1}
  180. test {Non existing command} {
  181. catch {r foobaredcommand} err
  182. string match ERR* $err
  183. } {1}
  184. test {RENAME basic usage} {
  185. r set mykey hello
  186. r rename mykey mykey1
  187. r rename mykey1 mykey2
  188. r get mykey2
  189. } {hello}
  190. test {RENAME source key should no longer exist} {
  191. r exists mykey
  192. } {0}
  193. test {RENAME against already existing key} {
  194. r set mykey a
  195. r set mykey2 b
  196. r rename mykey2 mykey
  197. set res [r get mykey]
  198. append res [r exists mykey2]
  199. } {b0}
  200. test {RENAMENX basic usage} {
  201. r del mykey
  202. r del mykey2
  203. r set mykey foobar
  204. r renamenx mykey mykey2
  205. set res [r get mykey2]
  206. append res [r exists mykey]
  207. } {foobar0}
  208. test {RENAMENX against already existing key} {
  209. r set mykey foo
  210. r set mykey2 bar
  211. r renamenx mykey mykey2
  212. } {0}
  213. test {RENAMENX against already existing key (2)} {
  214. set res [r get mykey]
  215. append res [r get mykey2]
  216. } {foobar}
  217. test {RENAME against non existing source key} {
  218. catch {r rename nokey foobar} err
  219. format $err
  220. } {ERR*}
  221. test {RENAME where source and dest key is the same} {
  222. catch {r rename mykey mykey} err
  223. format $err
  224. } {ERR*}
  225. test {DEL all keys again (DB 0)} {
  226. foreach key [r keys *] {
  227. r del $key
  228. }
  229. r dbsize
  230. } {0}
  231. test {DEL all keys again (DB 1)} {
  232. r select 10
  233. foreach key [r keys *] {
  234. r del $key
  235. }
  236. set res [r dbsize]
  237. r select 9
  238. format $res
  239. } {0}
  240. test {MOVE basic usage} {
  241. r set mykey foobar
  242. r move mykey 10
  243. set res {}
  244. lappend res [r exists mykey]
  245. lappend res [r dbsize]
  246. r select 10
  247. lappend res [r get mykey]
  248. lappend res [r dbsize]
  249. r select 9
  250. format $res
  251. } [list 0 0 foobar 1]
  252. test {MOVE against key existing in the target DB} {
  253. r set mykey hello
  254. r move mykey 10
  255. } {0}
  256. test {SET/GET keys in different DBs} {
  257. r set a hello
  258. r set b world
  259. r select 10
  260. r set a foo
  261. r set b bared
  262. r select 9
  263. set res {}
  264. lappend res [r get a]
  265. lappend res [r get b]
  266. r select 10
  267. lappend res [r get a]
  268. lappend res [r get b]
  269. r select 9
  270. format $res
  271. } {hello world foo bared}
  272. test {MGET} {
  273. r flushdb
  274. r set foo BAR
  275. r set bar FOO
  276. r mget foo bar
  277. } {BAR FOO}
  278. test {MGET against non existing key} {
  279. r mget foo baazz bar
  280. } {BAR {} FOO}
  281. test {MGET against non-string key} {
  282. r sadd myset ciao
  283. r sadd myset bau
  284. r mget foo baazz bar myset
  285. } {BAR {} FOO {}}
  286. test {RANDOMKEY} {
  287. r flushdb
  288. r set foo x
  289. r set bar y
  290. set foo_seen 0
  291. set bar_seen 0
  292. for {set i 0} {$i < 100} {incr i} {
  293. set rkey [r randomkey]
  294. if {$rkey eq {foo}} {
  295. set foo_seen 1
  296. }
  297. if {$rkey eq {bar}} {
  298. set bar_seen 1
  299. }
  300. }
  301. list $foo_seen $bar_seen
  302. } {1 1}
  303. test {RANDOMKEY against empty DB} {
  304. r flushdb
  305. r randomkey
  306. } {}
  307. test {RANDOMKEY regression 1} {
  308. r flushdb
  309. r set x 10
  310. r del x
  311. r randomkey
  312. } {}
  313. test {GETSET (set new value)} {
  314. list [r getset foo xyz] [r get foo]
  315. } {{} xyz}
  316. test {GETSET (replace old value)} {
  317. r set foo bar
  318. list [r getset foo xyz] [r get foo]
  319. } {bar xyz}
  320. test {MSET base case} {
  321. r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
  322. r mget x y z
  323. } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
  324. test {MSET wrong number of args} {
  325. catch {r mset x 10 y "foo bar" z} err
  326. format $err
  327. } {*wrong number*}
  328. test {MSETNX with already existent key} {
  329. list [r msetnx x1 xxx y2 yyy x 20] [r exists x1] [r exists y2]
  330. } {0 0 0}
  331. test {MSETNX with not existing keys} {
  332. list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2]
  333. } {1 xxx yyy}
  334. test "STRLEN against non-existing key" {
  335. assert_equal 0 [r strlen notakey]
  336. }
  337. test "STRLEN against integer-encoded value" {
  338. r set myinteger -555
  339. assert_equal 4 [r strlen myinteger]
  340. }
  341. test "STRLEN against plain string" {
  342. r set mystring "foozzz0123456789 baz"
  343. assert_equal 20 [r strlen mystring]
  344. }
  345. test "SETBIT against non-existing key" {
  346. r del mykey
  347. assert_equal 0 [r setbit mykey 1 1]
  348. assert_equal [binary format B* 01000000] [r get mykey]
  349. }
  350. test "SETBIT against string-encoded key" {
  351. # Ascii "@" is integer 64 = 01 00 00 00
  352. r set mykey "@"
  353. assert_equal 0 [r setbit mykey 2 1]
  354. assert_equal [binary format B* 01100000] [r get mykey]
  355. assert_equal 1 [r setbit mykey 1 0]
  356. assert_equal [binary format B* 00100000] [r get mykey]
  357. }
  358. test "SETBIT against integer-encoded key" {
  359. # Ascii "1" is integer 49 = 00 11 00 01
  360. r set mykey 1
  361. assert_encoding int mykey
  362. assert_equal 0 [r setbit mykey 6 1]
  363. assert_equal [binary format B* 00110011] [r get mykey]
  364. assert_equal 1 [r setbit mykey 2 0]
  365. assert_equal [binary format B* 00010011] [r get mykey]
  366. }
  367. test "SETBIT against key with wrong type" {
  368. r del mykey
  369. r lpush mykey "foo"
  370. assert_error "*wrong kind*" {r setbit mykey 0 1}
  371. }
  372. test "SETBIT with out of range bit offset" {
  373. r del mykey
  374. assert_error "*out of range*" {r setbit mykey [expr 4*1024*1024*1024] 1}
  375. assert_error "*out of range*" {r setbit mykey -1 1}
  376. }
  377. test "SETBIT with non-bit argument" {
  378. r del mykey
  379. assert_error "*out of range*" {r setbit mykey 0 -1}
  380. assert_error "*out of range*" {r setbit mykey 0 2}
  381. assert_error "*out of range*" {r setbit mykey 0 10}
  382. assert_error "*out of range*" {r setbit mykey 0 20}
  383. }
  384. test "SETBIT fuzzing" {
  385. set str ""
  386. set len [expr 256*8]
  387. r del mykey
  388. for {set i 0} {$i < 2000} {incr i} {
  389. set bitnum [randomInt $len]
  390. set bitval [randomInt 2]
  391. set fmt [format "%%-%ds%%d%%-s" $bitnum]
  392. set head [string range $str 0 $bitnum-1]
  393. set tail [string range $str $bitnum+1 end]
  394. set str [string map {" " 0} [format $fmt $head $bitval $tail]]
  395. r setbit mykey $bitnum $bitval
  396. assert_equal [binary format B* $str] [r get mykey]
  397. }
  398. }
  399. test "GETBIT against non-existing key" {
  400. r del mykey
  401. assert_equal 0 [r getbit mykey 0]
  402. }
  403. test "GETBIT against string-encoded key" {
  404. # Single byte with 2nd and 3rd bit set
  405. r set mykey "`"
  406. # In-range
  407. assert_equal 0 [r getbit mykey 0]
  408. assert_equal 1 [r getbit mykey 1]
  409. assert_equal 1 [r getbit mykey 2]
  410. assert_equal 0 [r getbit mykey 3]
  411. # Out-range
  412. assert_equal 0 [r getbit mykey 8]
  413. assert_equal 0 [r getbit mykey 100]
  414. assert_equal 0 [r getbit mykey 10000]
  415. }
  416. test "GETBIT against integer-encoded key" {
  417. r set mykey 1
  418. assert_encoding int mykey
  419. # Ascii "1" is integer 49 = 00 11 00 01
  420. assert_equal 0 [r getbit mykey 0]
  421. assert_equal 0 [r getbit mykey 1]
  422. assert_equal 1 [r getbit mykey 2]
  423. assert_equal 1 [r getbit mykey 3]
  424. # Out-range
  425. assert_equal 0 [r getbit mykey 8]
  426. assert_equal 0 [r getbit mykey 100]
  427. assert_equal 0 [r getbit mykey 10000]
  428. }
  429. test "SETRANGE against non-existing key" {
  430. r del mykey
  431. assert_equal 3 [r setrange mykey 0 foo]
  432. assert_equal "foo" [r get mykey]
  433. r del mykey
  434. assert_equal 0 [r setrange mykey 0 ""]
  435. assert_equal 0 [r exists mykey]
  436. r del mykey
  437. assert_equal 4 [r setrange mykey 1 foo]
  438. assert_equal "\000foo" [r get mykey]
  439. }
  440. test "SETRANGE against string-encoded key" {
  441. r set mykey "foo"
  442. assert_equal 3 [r setrange mykey 0 b]
  443. assert_equal "boo" [r get mykey]
  444. r set mykey "foo"
  445. assert_equal 3 [r setrange mykey 0 ""]
  446. assert_equal "foo" [r get mykey]
  447. r set mykey "foo"
  448. assert_equal 3 [r setrange mykey 1 b]
  449. assert_equal "fbo" [r get mykey]
  450. r set mykey "foo"
  451. assert_equal 7 [r setrange mykey 4 bar]
  452. assert_equal "foo\000bar" [r get mykey]
  453. }
  454. test "SETRANGE against integer-encoded key" {
  455. r set mykey 1234
  456. assert_encoding int mykey
  457. assert_equal 4 [r setrange mykey 0 2]
  458. assert_encoding raw mykey
  459. assert_equal 2234 [r get mykey]
  460. # Shouldn't change encoding when nothing is set
  461. r set mykey 1234
  462. assert_encoding int mykey
  463. assert_equal 4 [r setrange mykey 0 ""]
  464. assert_encoding int mykey
  465. assert_equal 1234 [r get mykey]
  466. r set mykey 1234
  467. assert_encoding int mykey
  468. assert_equal 4 [r setrange mykey 1 3]
  469. assert_encoding raw mykey
  470. assert_equal 1334 [r get mykey]
  471. r set mykey 1234
  472. assert_encoding int mykey
  473. assert_equal 6 [r setrange mykey 5 2]
  474. assert_encoding raw mykey
  475. assert_equal "1234\0002" [r get mykey]
  476. }
  477. test "SETRANGE against key with wrong type" {
  478. r del mykey
  479. r lpush mykey "foo"
  480. assert_error "*wrong kind*" {r setrange mykey 0 bar}
  481. }
  482. test "SETRANGE with out of range offset" {
  483. r del mykey
  484. assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
  485. r set mykey "hello"
  486. assert_error "*out of range*" {r setrange mykey -1 world}
  487. assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
  488. }
  489. test "GETRANGE against non-existing key" {
  490. r del mykey
  491. assert_equal "" [r getrange mykey 0 -1]
  492. }
  493. test "GETRANGE against string value" {
  494. r set mykey "Hello World"
  495. assert_equal "Hell" [r getrange mykey 0 3]
  496. assert_equal "Hello World" [r getrange mykey 0 -1]
  497. assert_equal "orld" [r getrange mykey -4 -1]
  498. assert_equal "" [r getrange mykey 5 3]
  499. assert_equal " World" [r getrange mykey 5 5000]
  500. assert_equal "Hello World" [r getrange mykey -5000 10000]
  501. }
  502. test "GETRANGE against integer-encoded value" {
  503. r set mykey 1234
  504. assert_equal "123" [r getrange mykey 0 2]
  505. assert_equal "1234" [r getrange mykey 0 -1]
  506. assert_equal "234" [r getrange mykey -3 -1]
  507. assert_equal "" [r getrange mykey 5 3]
  508. assert_equal "4" [r getrange mykey 3 5000]
  509. assert_equal "1234" [r getrange mykey -5000 10000]
  510. }
  511. test "GETRANGE fuzzing" {
  512. for {set i 0} {$i < 1000} {incr i} {
  513. r set bin [set bin [randstring 0 1024 binary]]
  514. set _start [set start [randomInt 1500]]
  515. set _end [set end [randomInt 1500]]
  516. if {$_start < 0} {set _start "end-[abs($_start)-1]"}
  517. if {$_end < 0} {set _end "end-[abs($_end)-1]"}
  518. assert_equal [string range $bin $_start $_end] [r getrange bin $start $end]
  519. }
  520. }
  521. }