string.tcl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. start_server {tags {"string"}} {
  2. test {SET and GET an item} {
  3. r set x foobar
  4. r get x
  5. } {foobar}
  6. test {SET and GET an empty item} {
  7. r set x {}
  8. r get x
  9. } {}
  10. test {Very big payload in GET/SET} {
  11. set buf [string repeat "abcd" 1000000]
  12. r set foo $buf
  13. r get foo
  14. } [string repeat "abcd" 1000000]
  15. tags {"slow"} {
  16. test {Very big payload random access} {
  17. set err {}
  18. array set payload {}
  19. for {set j 0} {$j < 100} {incr j} {
  20. set size [expr 1+[randomInt 100000]]
  21. set buf [string repeat "pl-$j" $size]
  22. set payload($j) $buf
  23. r set bigpayload_$j $buf
  24. }
  25. for {set j 0} {$j < 1000} {incr j} {
  26. set index [randomInt 100]
  27. set buf [r get bigpayload_$index]
  28. if {$buf != $payload($index)} {
  29. set err "Values differ: I set '$payload($index)' but I read back '$buf'"
  30. break
  31. }
  32. }
  33. unset payload
  34. set _ $err
  35. } {}
  36. test {SET 10000 numeric keys and access all them in reverse order} {
  37. r flushdb
  38. set err {}
  39. for {set x 0} {$x < 10000} {incr x} {
  40. r set $x $x
  41. }
  42. set sum 0
  43. for {set x 9999} {$x >= 0} {incr x -1} {
  44. set val [r get $x]
  45. if {$val ne $x} {
  46. set err "Element at position $x is $val instead of $x"
  47. break
  48. }
  49. }
  50. set _ $err
  51. } {}
  52. test {DBSIZE should be 10000 now} {
  53. r dbsize
  54. } {10000}
  55. }
  56. test "SETNX target key missing" {
  57. r del novar
  58. assert_equal 1 [r setnx novar foobared]
  59. assert_equal "foobared" [r get novar]
  60. }
  61. test "SETNX target key exists" {
  62. r set novar foobared
  63. assert_equal 0 [r setnx novar blabla]
  64. assert_equal "foobared" [r get novar]
  65. }
  66. test "SETNX against not-expired volatile key" {
  67. r set x 10
  68. r expire x 10000
  69. assert_equal 0 [r setnx x 20]
  70. assert_equal 10 [r get x]
  71. }
  72. test "SETNX against expired volatile key" {
  73. # Make it very unlikely for the key this test uses to be expired by the
  74. # active expiry cycle. This is tightly coupled to the implementation of
  75. # active expiry and dbAdd() but currently the only way to test that
  76. # SETNX expires a key when it should have been.
  77. for {set x 0} {$x < 9999} {incr x} {
  78. r setex key-$x 3600 value
  79. }
  80. # This will be one of 10000 expiring keys. A cycle is executed every
  81. # 100ms, sampling 10 keys for being expired or not. This key will be
  82. # expired for at most 1s when we wait 2s, resulting in a total sample
  83. # of 100 keys. The probability of the success of this test being a
  84. # false positive is therefore approx. 1%.
  85. r set x 10
  86. r expire x 1
  87. # Wait for the key to expire
  88. after 2000
  89. assert_equal 1 [r setnx x 20]
  90. assert_equal 20 [r get x]
  91. }
  92. test {MGET} {
  93. r flushdb
  94. r set foo BAR
  95. r set bar FOO
  96. r mget foo bar
  97. } {BAR FOO}
  98. test {MGET against non existing key} {
  99. r mget foo baazz bar
  100. } {BAR {} FOO}
  101. test {MGET against non-string key} {
  102. r sadd myset ciao
  103. r sadd myset bau
  104. r mget foo baazz bar myset
  105. } {BAR {} FOO {}}
  106. test {GETSET (set new value)} {
  107. r del foo
  108. list [r getset foo xyz] [r get foo]
  109. } {{} xyz}
  110. test {GETSET (replace old value)} {
  111. r set foo bar
  112. list [r getset foo xyz] [r get foo]
  113. } {bar xyz}
  114. test {MSET base case} {
  115. r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
  116. r mget x y z
  117. } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
  118. test {MSET wrong number of args} {
  119. catch {r mset x 10 y "foo bar" z} err
  120. format $err
  121. } {*wrong number*}
  122. test {MSETNX with already existent key} {
  123. list [r msetnx x1 xxx y2 yyy x 20] [r exists x1] [r exists y2]
  124. } {0 0 0}
  125. test {MSETNX with not existing keys} {
  126. list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2]
  127. } {1 xxx yyy}
  128. test "STRLEN against non-existing key" {
  129. assert_equal 0 [r strlen notakey]
  130. }
  131. test "STRLEN against integer-encoded value" {
  132. r set myinteger -555
  133. assert_equal 4 [r strlen myinteger]
  134. }
  135. test "STRLEN against plain string" {
  136. r set mystring "foozzz0123456789 baz"
  137. assert_equal 20 [r strlen mystring]
  138. }
  139. test "SETBIT against non-existing key" {
  140. r del mykey
  141. assert_equal 0 [r setbit mykey 1 1]
  142. assert_equal [binary format B* 01000000] [r get mykey]
  143. }
  144. test "SETBIT against string-encoded key" {
  145. # Ascii "@" is integer 64 = 01 00 00 00
  146. r set mykey "@"
  147. assert_equal 0 [r setbit mykey 2 1]
  148. assert_equal [binary format B* 01100000] [r get mykey]
  149. assert_equal 1 [r setbit mykey 1 0]
  150. assert_equal [binary format B* 00100000] [r get mykey]
  151. }
  152. test "SETBIT against integer-encoded key" {
  153. # Ascii "1" is integer 49 = 00 11 00 01
  154. r set mykey 1
  155. assert_encoding int mykey
  156. assert_equal 0 [r setbit mykey 6 1]
  157. assert_equal [binary format B* 00110011] [r get mykey]
  158. assert_equal 1 [r setbit mykey 2 0]
  159. assert_equal [binary format B* 00010011] [r get mykey]
  160. }
  161. test "SETBIT against key with wrong type" {
  162. r del mykey
  163. r lpush mykey "foo"
  164. assert_error "WRONGTYPE*" {r setbit mykey 0 1}
  165. }
  166. test "SETBIT with out of range bit offset" {
  167. r del mykey
  168. assert_error "*out of range*" {r setbit mykey [expr 4*1024*1024*1024] 1}
  169. assert_error "*out of range*" {r setbit mykey -1 1}
  170. }
  171. test "SETBIT with non-bit argument" {
  172. r del mykey
  173. assert_error "*out of range*" {r setbit mykey 0 -1}
  174. assert_error "*out of range*" {r setbit mykey 0 2}
  175. assert_error "*out of range*" {r setbit mykey 0 10}
  176. assert_error "*out of range*" {r setbit mykey 0 20}
  177. }
  178. test "SETBIT fuzzing" {
  179. set str ""
  180. set len [expr 256*8]
  181. r del mykey
  182. for {set i 0} {$i < 2000} {incr i} {
  183. set bitnum [randomInt $len]
  184. set bitval [randomInt 2]
  185. set fmt [format "%%-%ds%%d%%-s" $bitnum]
  186. set head [string range $str 0 $bitnum-1]
  187. set tail [string range $str $bitnum+1 end]
  188. set str [string map {" " 0} [format $fmt $head $bitval $tail]]
  189. r setbit mykey $bitnum $bitval
  190. assert_equal [binary format B* $str] [r get mykey]
  191. }
  192. }
  193. test "GETBIT against non-existing key" {
  194. r del mykey
  195. assert_equal 0 [r getbit mykey 0]
  196. }
  197. test "GETBIT against string-encoded key" {
  198. # Single byte with 2nd and 3rd bit set
  199. r set mykey "`"
  200. # In-range
  201. assert_equal 0 [r getbit mykey 0]
  202. assert_equal 1 [r getbit mykey 1]
  203. assert_equal 1 [r getbit mykey 2]
  204. assert_equal 0 [r getbit mykey 3]
  205. # Out-range
  206. assert_equal 0 [r getbit mykey 8]
  207. assert_equal 0 [r getbit mykey 100]
  208. assert_equal 0 [r getbit mykey 10000]
  209. }
  210. test "GETBIT against integer-encoded key" {
  211. r set mykey 1
  212. assert_encoding int mykey
  213. # Ascii "1" is integer 49 = 00 11 00 01
  214. assert_equal 0 [r getbit mykey 0]
  215. assert_equal 0 [r getbit mykey 1]
  216. assert_equal 1 [r getbit mykey 2]
  217. assert_equal 1 [r getbit mykey 3]
  218. # Out-range
  219. assert_equal 0 [r getbit mykey 8]
  220. assert_equal 0 [r getbit mykey 100]
  221. assert_equal 0 [r getbit mykey 10000]
  222. }
  223. test "SETRANGE against non-existing key" {
  224. r del mykey
  225. assert_equal 3 [r setrange mykey 0 foo]
  226. assert_equal "foo" [r get mykey]
  227. r del mykey
  228. assert_equal 0 [r setrange mykey 0 ""]
  229. assert_equal 0 [r exists mykey]
  230. r del mykey
  231. assert_equal 4 [r setrange mykey 1 foo]
  232. assert_equal "\000foo" [r get mykey]
  233. }
  234. test "SETRANGE against string-encoded key" {
  235. r set mykey "foo"
  236. assert_equal 3 [r setrange mykey 0 b]
  237. assert_equal "boo" [r get mykey]
  238. r set mykey "foo"
  239. assert_equal 3 [r setrange mykey 0 ""]
  240. assert_equal "foo" [r get mykey]
  241. r set mykey "foo"
  242. assert_equal 3 [r setrange mykey 1 b]
  243. assert_equal "fbo" [r get mykey]
  244. r set mykey "foo"
  245. assert_equal 7 [r setrange mykey 4 bar]
  246. assert_equal "foo\000bar" [r get mykey]
  247. }
  248. test "SETRANGE against integer-encoded key" {
  249. r set mykey 1234
  250. assert_encoding int mykey
  251. assert_equal 4 [r setrange mykey 0 2]
  252. assert_encoding raw mykey
  253. assert_equal 2234 [r get mykey]
  254. # Shouldn't change encoding when nothing is set
  255. r set mykey 1234
  256. assert_encoding int mykey
  257. assert_equal 4 [r setrange mykey 0 ""]
  258. assert_encoding int mykey
  259. assert_equal 1234 [r get mykey]
  260. r set mykey 1234
  261. assert_encoding int mykey
  262. assert_equal 4 [r setrange mykey 1 3]
  263. assert_encoding raw mykey
  264. assert_equal 1334 [r get mykey]
  265. r set mykey 1234
  266. assert_encoding int mykey
  267. assert_equal 6 [r setrange mykey 5 2]
  268. assert_encoding raw mykey
  269. assert_equal "1234\0002" [r get mykey]
  270. }
  271. test "SETRANGE against key with wrong type" {
  272. r del mykey
  273. r lpush mykey "foo"
  274. assert_error "WRONGTYPE*" {r setrange mykey 0 bar}
  275. }
  276. test "SETRANGE with out of range offset" {
  277. r del mykey
  278. assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
  279. r set mykey "hello"
  280. assert_error "*out of range*" {r setrange mykey -1 world}
  281. assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
  282. }
  283. test "GETRANGE against non-existing key" {
  284. r del mykey
  285. assert_equal "" [r getrange mykey 0 -1]
  286. }
  287. test "GETRANGE against string value" {
  288. r set mykey "Hello World"
  289. assert_equal "Hell" [r getrange mykey 0 3]
  290. assert_equal "Hello World" [r getrange mykey 0 -1]
  291. assert_equal "orld" [r getrange mykey -4 -1]
  292. assert_equal "" [r getrange mykey 5 3]
  293. assert_equal " World" [r getrange mykey 5 5000]
  294. assert_equal "Hello World" [r getrange mykey -5000 10000]
  295. }
  296. test "GETRANGE against integer-encoded value" {
  297. r set mykey 1234
  298. assert_equal "123" [r getrange mykey 0 2]
  299. assert_equal "1234" [r getrange mykey 0 -1]
  300. assert_equal "234" [r getrange mykey -3 -1]
  301. assert_equal "" [r getrange mykey 5 3]
  302. assert_equal "4" [r getrange mykey 3 5000]
  303. assert_equal "1234" [r getrange mykey -5000 10000]
  304. }
  305. test "GETRANGE fuzzing" {
  306. for {set i 0} {$i < 1000} {incr i} {
  307. r set bin [set bin [randstring 0 1024 binary]]
  308. set _start [set start [randomInt 1500]]
  309. set _end [set end [randomInt 1500]]
  310. if {$_start < 0} {set _start "end-[abs($_start)-1]"}
  311. if {$_end < 0} {set _end "end-[abs($_end)-1]"}
  312. assert_equal [string range $bin $_start $_end] [r getrange bin $start $end]
  313. }
  314. }
  315. test {Extended SET can detect syntax errors} {
  316. set e {}
  317. catch {r set foo bar non-existing-option} e
  318. set e
  319. } {*syntax*}
  320. test {Extended SET NX option} {
  321. r del foo
  322. set v1 [r set foo 1 nx]
  323. set v2 [r set foo 2 nx]
  324. list $v1 $v2 [r get foo]
  325. } {OK {} 1}
  326. test {Extended SET XX option} {
  327. r del foo
  328. set v1 [r set foo 1 xx]
  329. r set foo bar
  330. set v2 [r set foo 2 xx]
  331. list $v1 $v2 [r get foo]
  332. } {{} OK 2}
  333. test {Extended SET EX option} {
  334. r del foo
  335. r set foo bar ex 10
  336. set ttl [r ttl foo]
  337. assert {$ttl <= 10 && $ttl > 5}
  338. }
  339. test {Extended SET PX option} {
  340. r del foo
  341. r set foo bar px 10000
  342. set ttl [r ttl foo]
  343. assert {$ttl <= 10 && $ttl > 5}
  344. }
  345. test {Extended SET using multiple options at once} {
  346. r set foo val
  347. assert {[r set foo bar xx px 10000] eq {OK}}
  348. set ttl [r ttl foo]
  349. assert {$ttl <= 10 && $ttl > 5}
  350. }
  351. test {GETRANGE with huge ranges, Github issue #1844} {
  352. r set foo bar
  353. r getrange foo 0 4294967297
  354. } {bar}
  355. }