2
0

basic.tcl 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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 (left)} {
  106. r set novar " 11"
  107. catch {r incr novar} err
  108. format $err
  109. } {ERR*}
  110. test {INCR fails against key with spaces (right)} {
  111. r set novar "11 "
  112. catch {r incr novar} err
  113. format $err
  114. } {ERR*}
  115. test {INCR fails against key with spaces (both)} {
  116. r set novar " 11 "
  117. catch {r incr novar} err
  118. format $err
  119. } {ERR*}
  120. test {INCR fails against a key holding a list} {
  121. r rpush mylist 1
  122. catch {r incr mylist} err
  123. r rpop mylist
  124. format $err
  125. } {WRONGTYPE*}
  126. test {DECRBY over 32bit value with over 32bit increment, negative res} {
  127. r set novar 17179869184
  128. r decrby novar 17179869185
  129. } {-1}
  130. test {INCRBYFLOAT against non existing key} {
  131. r del novar
  132. list [roundFloat [r incrbyfloat novar 1]] \
  133. [roundFloat [r get novar]] \
  134. [roundFloat [r incrbyfloat novar 0.25]] \
  135. [roundFloat [r get novar]]
  136. } {1 1 1.25 1.25}
  137. test {INCRBYFLOAT against key originally set with SET} {
  138. r set novar 1.5
  139. roundFloat [r incrbyfloat novar 1.5]
  140. } {3}
  141. test {INCRBYFLOAT over 32bit value} {
  142. r set novar 17179869184
  143. r incrbyfloat novar 1.5
  144. } {17179869185.5}
  145. test {INCRBYFLOAT over 32bit value with over 32bit increment} {
  146. r set novar 17179869184
  147. r incrbyfloat novar 17179869184
  148. } {34359738368}
  149. test {INCRBYFLOAT fails against key with spaces (left)} {
  150. set err {}
  151. r set novar " 11"
  152. catch {r incrbyfloat novar 1.0} err
  153. format $err
  154. } {ERR*valid*}
  155. test {INCRBYFLOAT fails against key with spaces (right)} {
  156. set err {}
  157. r set novar "11 "
  158. catch {r incrbyfloat novar 1.0} err
  159. format $err
  160. } {ERR*valid*}
  161. test {INCRBYFLOAT fails against key with spaces (both)} {
  162. set err {}
  163. r set novar " 11 "
  164. catch {r incrbyfloat novar 1.0} err
  165. format $err
  166. } {ERR*valid*}
  167. test {INCRBYFLOAT fails against a key holding a list} {
  168. r del mylist
  169. set err {}
  170. r rpush mylist 1
  171. catch {r incrbyfloat mylist 1.0} err
  172. r del mylist
  173. format $err
  174. } {WRONGTYPE*}
  175. test {INCRBYFLOAT does not allow NaN or Infinity} {
  176. r set foo 0
  177. set err {}
  178. catch {r incrbyfloat foo +inf} err
  179. set err
  180. # p.s. no way I can force NaN to test it from the API because
  181. # there is no way to increment / decrement by infinity nor to
  182. # perform divisions.
  183. } {ERR*would produce*}
  184. test {INCRBYFLOAT decrement} {
  185. r set foo 1
  186. roundFloat [r incrbyfloat foo -1.1]
  187. } {-0.1}
  188. test "SETNX target key missing" {
  189. r del novar
  190. assert_equal 1 [r setnx novar foobared]
  191. assert_equal "foobared" [r get novar]
  192. }
  193. test "SETNX target key exists" {
  194. r set novar foobared
  195. assert_equal 0 [r setnx novar blabla]
  196. assert_equal "foobared" [r get novar]
  197. }
  198. test "SETNX against not-expired volatile key" {
  199. r set x 10
  200. r expire x 10000
  201. assert_equal 0 [r setnx x 20]
  202. assert_equal 10 [r get x]
  203. }
  204. test "SETNX against expired volatile key" {
  205. # Make it very unlikely for the key this test uses to be expired by the
  206. # active expiry cycle. This is tightly coupled to the implementation of
  207. # active expiry and dbAdd() but currently the only way to test that
  208. # SETNX expires a key when it should have been.
  209. for {set x 0} {$x < 9999} {incr x} {
  210. r setex key-$x 3600 value
  211. }
  212. # This will be one of 10000 expiring keys. A cycle is executed every
  213. # 100ms, sampling 10 keys for being expired or not. This key will be
  214. # expired for at most 1s when we wait 2s, resulting in a total sample
  215. # of 100 keys. The probability of the success of this test being a
  216. # false positive is therefore approx. 1%.
  217. r set x 10
  218. r expire x 1
  219. # Wait for the key to expire
  220. after 2000
  221. assert_equal 1 [r setnx x 20]
  222. assert_equal 20 [r get x]
  223. }
  224. test "DEL against expired key" {
  225. r debug set-active-expire 0
  226. r setex keyExpire 1 valExpire
  227. after 1100
  228. assert_equal 0 [r del keyExpire]
  229. r debug set-active-expire 1
  230. }
  231. test {EXISTS} {
  232. set res {}
  233. r set newkey test
  234. append res [r exists newkey]
  235. r del newkey
  236. append res [r exists newkey]
  237. } {10}
  238. test {Zero length value in key. SET/GET/EXISTS} {
  239. r set emptykey {}
  240. set res [r get emptykey]
  241. append res [r exists emptykey]
  242. r del emptykey
  243. append res [r exists emptykey]
  244. } {10}
  245. test {Commands pipelining} {
  246. set fd [r channel]
  247. puts -nonewline $fd "SET k1 xyzk\r\nGET k1\r\nPING\r\n"
  248. flush $fd
  249. set res {}
  250. append res [string match OK* [r read]]
  251. append res [r read]
  252. append res [string match PONG* [r read]]
  253. format $res
  254. } {1xyzk1}
  255. test {Non existing command} {
  256. catch {r foobaredcommand} err
  257. string match ERR* $err
  258. } {1}
  259. test {RENAME basic usage} {
  260. r set mykey hello
  261. r rename mykey mykey1
  262. r rename mykey1 mykey2
  263. r get mykey2
  264. } {hello}
  265. test {RENAME source key should no longer exist} {
  266. r exists mykey
  267. } {0}
  268. test {RENAME against already existing key} {
  269. r set mykey a
  270. r set mykey2 b
  271. r rename mykey2 mykey
  272. set res [r get mykey]
  273. append res [r exists mykey2]
  274. } {b0}
  275. test {RENAMENX basic usage} {
  276. r del mykey
  277. r del mykey2
  278. r set mykey foobar
  279. r renamenx mykey mykey2
  280. set res [r get mykey2]
  281. append res [r exists mykey]
  282. } {foobar0}
  283. test {RENAMENX against already existing key} {
  284. r set mykey foo
  285. r set mykey2 bar
  286. r renamenx mykey mykey2
  287. } {0}
  288. test {RENAMENX against already existing key (2)} {
  289. set res [r get mykey]
  290. append res [r get mykey2]
  291. } {foobar}
  292. test {RENAME against non existing source key} {
  293. catch {r rename nokey foobar} err
  294. format $err
  295. } {ERR*}
  296. test {RENAME where source and dest key is the same} {
  297. catch {r rename mykey mykey} err
  298. format $err
  299. } {ERR*}
  300. test {RENAME with volatile key, should move the TTL as well} {
  301. r del mykey mykey2
  302. r set mykey foo
  303. r expire mykey 100
  304. assert {[r ttl mykey] > 95 && [r ttl mykey] <= 100}
  305. r rename mykey mykey2
  306. assert {[r ttl mykey2] > 95 && [r ttl mykey2] <= 100}
  307. }
  308. test {RENAME with volatile key, should not inherit TTL of target key} {
  309. r del mykey mykey2
  310. r set mykey foo
  311. r set mykey2 bar
  312. r expire mykey2 100
  313. assert {[r ttl mykey] == -1 && [r ttl mykey2] > 0}
  314. r rename mykey mykey2
  315. r ttl mykey2
  316. } {-1}
  317. test {DEL all keys again (DB 0)} {
  318. foreach key [r keys *] {
  319. r del $key
  320. }
  321. r dbsize
  322. } {0}
  323. test {DEL all keys again (DB 1)} {
  324. r select 10
  325. foreach key [r keys *] {
  326. r del $key
  327. }
  328. set res [r dbsize]
  329. r select 9
  330. format $res
  331. } {0}
  332. test {MOVE basic usage} {
  333. r set mykey foobar
  334. r move mykey 10
  335. set res {}
  336. lappend res [r exists mykey]
  337. lappend res [r dbsize]
  338. r select 10
  339. lappend res [r get mykey]
  340. lappend res [r dbsize]
  341. r select 9
  342. format $res
  343. } [list 0 0 foobar 1]
  344. test {MOVE against key existing in the target DB} {
  345. r set mykey hello
  346. r move mykey 10
  347. } {0}
  348. test {SET/GET keys in different DBs} {
  349. r set a hello
  350. r set b world
  351. r select 10
  352. r set a foo
  353. r set b bared
  354. r select 9
  355. set res {}
  356. lappend res [r get a]
  357. lappend res [r get b]
  358. r select 10
  359. lappend res [r get a]
  360. lappend res [r get b]
  361. r select 9
  362. format $res
  363. } {hello world foo bared}
  364. test {MGET} {
  365. r flushdb
  366. r set foo BAR
  367. r set bar FOO
  368. r mget foo bar
  369. } {BAR FOO}
  370. test {MGET against non existing key} {
  371. r mget foo baazz bar
  372. } {BAR {} FOO}
  373. test {MGET against non-string key} {
  374. r sadd myset ciao
  375. r sadd myset bau
  376. r mget foo baazz bar myset
  377. } {BAR {} FOO {}}
  378. test {RANDOMKEY} {
  379. r flushdb
  380. r set foo x
  381. r set bar y
  382. set foo_seen 0
  383. set bar_seen 0
  384. for {set i 0} {$i < 100} {incr i} {
  385. set rkey [r randomkey]
  386. if {$rkey eq {foo}} {
  387. set foo_seen 1
  388. }
  389. if {$rkey eq {bar}} {
  390. set bar_seen 1
  391. }
  392. }
  393. list $foo_seen $bar_seen
  394. } {1 1}
  395. test {RANDOMKEY against empty DB} {
  396. r flushdb
  397. r randomkey
  398. } {}
  399. test {RANDOMKEY regression 1} {
  400. r flushdb
  401. r set x 10
  402. r del x
  403. r randomkey
  404. } {}
  405. test {GETSET (set new value)} {
  406. list [r getset foo xyz] [r get foo]
  407. } {{} xyz}
  408. test {GETSET (replace old value)} {
  409. r set foo bar
  410. list [r getset foo xyz] [r get foo]
  411. } {bar xyz}
  412. test {MSET base case} {
  413. r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n"
  414. r mget x y z
  415. } [list 10 {foo bar} "x x x x x x x\n\n\r\n"]
  416. test {MSET wrong number of args} {
  417. catch {r mset x 10 y "foo bar" z} err
  418. format $err
  419. } {*wrong number*}
  420. test {MSETNX with already existent key} {
  421. list [r msetnx x1 xxx y2 yyy x 20] [r exists x1] [r exists y2]
  422. } {0 0 0}
  423. test {MSETNX with not existing keys} {
  424. list [r msetnx x1 xxx y2 yyy] [r get x1] [r get y2]
  425. } {1 xxx yyy}
  426. test "STRLEN against non-existing key" {
  427. assert_equal 0 [r strlen notakey]
  428. }
  429. test "STRLEN against integer-encoded value" {
  430. r set myinteger -555
  431. assert_equal 4 [r strlen myinteger]
  432. }
  433. test "STRLEN against plain string" {
  434. r set mystring "foozzz0123456789 baz"
  435. assert_equal 20 [r strlen mystring]
  436. }
  437. test "SETBIT against non-existing key" {
  438. r del mykey
  439. assert_equal 0 [r setbit mykey 1 1]
  440. assert_equal [binary format B* 01000000] [r get mykey]
  441. }
  442. test "SETBIT against string-encoded key" {
  443. # Ascii "@" is integer 64 = 01 00 00 00
  444. r set mykey "@"
  445. assert_equal 0 [r setbit mykey 2 1]
  446. assert_equal [binary format B* 01100000] [r get mykey]
  447. assert_equal 1 [r setbit mykey 1 0]
  448. assert_equal [binary format B* 00100000] [r get mykey]
  449. }
  450. test "SETBIT against integer-encoded key" {
  451. # Ascii "1" is integer 49 = 00 11 00 01
  452. r set mykey 1
  453. assert_encoding int mykey
  454. assert_equal 0 [r setbit mykey 6 1]
  455. assert_equal [binary format B* 00110011] [r get mykey]
  456. assert_equal 1 [r setbit mykey 2 0]
  457. assert_equal [binary format B* 00010011] [r get mykey]
  458. }
  459. test "SETBIT against key with wrong type" {
  460. r del mykey
  461. r lpush mykey "foo"
  462. assert_error "WRONGTYPE*" {r setbit mykey 0 1}
  463. }
  464. test "SETBIT with out of range bit offset" {
  465. r del mykey
  466. assert_error "*out of range*" {r setbit mykey [expr 4*1024*1024*1024] 1}
  467. assert_error "*out of range*" {r setbit mykey -1 1}
  468. }
  469. test "SETBIT with non-bit argument" {
  470. r del mykey
  471. assert_error "*out of range*" {r setbit mykey 0 -1}
  472. assert_error "*out of range*" {r setbit mykey 0 2}
  473. assert_error "*out of range*" {r setbit mykey 0 10}
  474. assert_error "*out of range*" {r setbit mykey 0 20}
  475. }
  476. test "SETBIT fuzzing" {
  477. set str ""
  478. set len [expr 256*8]
  479. r del mykey
  480. for {set i 0} {$i < 2000} {incr i} {
  481. set bitnum [randomInt $len]
  482. set bitval [randomInt 2]
  483. set fmt [format "%%-%ds%%d%%-s" $bitnum]
  484. set head [string range $str 0 $bitnum-1]
  485. set tail [string range $str $bitnum+1 end]
  486. set str [string map {" " 0} [format $fmt $head $bitval $tail]]
  487. r setbit mykey $bitnum $bitval
  488. assert_equal [binary format B* $str] [r get mykey]
  489. }
  490. }
  491. test "GETBIT against non-existing key" {
  492. r del mykey
  493. assert_equal 0 [r getbit mykey 0]
  494. }
  495. test "GETBIT against string-encoded key" {
  496. # Single byte with 2nd and 3rd bit set
  497. r set mykey "`"
  498. # In-range
  499. assert_equal 0 [r getbit mykey 0]
  500. assert_equal 1 [r getbit mykey 1]
  501. assert_equal 1 [r getbit mykey 2]
  502. assert_equal 0 [r getbit mykey 3]
  503. # Out-range
  504. assert_equal 0 [r getbit mykey 8]
  505. assert_equal 0 [r getbit mykey 100]
  506. assert_equal 0 [r getbit mykey 10000]
  507. }
  508. test "GETBIT against integer-encoded key" {
  509. r set mykey 1
  510. assert_encoding int mykey
  511. # Ascii "1" is integer 49 = 00 11 00 01
  512. assert_equal 0 [r getbit mykey 0]
  513. assert_equal 0 [r getbit mykey 1]
  514. assert_equal 1 [r getbit mykey 2]
  515. assert_equal 1 [r getbit mykey 3]
  516. # Out-range
  517. assert_equal 0 [r getbit mykey 8]
  518. assert_equal 0 [r getbit mykey 100]
  519. assert_equal 0 [r getbit mykey 10000]
  520. }
  521. test "SETRANGE against non-existing key" {
  522. r del mykey
  523. assert_equal 3 [r setrange mykey 0 foo]
  524. assert_equal "foo" [r get mykey]
  525. r del mykey
  526. assert_equal 0 [r setrange mykey 0 ""]
  527. assert_equal 0 [r exists mykey]
  528. r del mykey
  529. assert_equal 4 [r setrange mykey 1 foo]
  530. assert_equal "\000foo" [r get mykey]
  531. }
  532. test "SETRANGE against string-encoded key" {
  533. r set mykey "foo"
  534. assert_equal 3 [r setrange mykey 0 b]
  535. assert_equal "boo" [r get mykey]
  536. r set mykey "foo"
  537. assert_equal 3 [r setrange mykey 0 ""]
  538. assert_equal "foo" [r get mykey]
  539. r set mykey "foo"
  540. assert_equal 3 [r setrange mykey 1 b]
  541. assert_equal "fbo" [r get mykey]
  542. r set mykey "foo"
  543. assert_equal 7 [r setrange mykey 4 bar]
  544. assert_equal "foo\000bar" [r get mykey]
  545. }
  546. test "SETRANGE against integer-encoded key" {
  547. r set mykey 1234
  548. assert_encoding int mykey
  549. assert_equal 4 [r setrange mykey 0 2]
  550. assert_encoding raw mykey
  551. assert_equal 2234 [r get mykey]
  552. # Shouldn't change encoding when nothing is set
  553. r set mykey 1234
  554. assert_encoding int mykey
  555. assert_equal 4 [r setrange mykey 0 ""]
  556. assert_encoding int mykey
  557. assert_equal 1234 [r get mykey]
  558. r set mykey 1234
  559. assert_encoding int mykey
  560. assert_equal 4 [r setrange mykey 1 3]
  561. assert_encoding raw mykey
  562. assert_equal 1334 [r get mykey]
  563. r set mykey 1234
  564. assert_encoding int mykey
  565. assert_equal 6 [r setrange mykey 5 2]
  566. assert_encoding raw mykey
  567. assert_equal "1234\0002" [r get mykey]
  568. }
  569. test "SETRANGE against key with wrong type" {
  570. r del mykey
  571. r lpush mykey "foo"
  572. assert_error "WRONGTYPE*" {r setrange mykey 0 bar}
  573. }
  574. test "SETRANGE with out of range offset" {
  575. r del mykey
  576. assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
  577. r set mykey "hello"
  578. assert_error "*out of range*" {r setrange mykey -1 world}
  579. assert_error "*maximum allowed size*" {r setrange mykey [expr 512*1024*1024-4] world}
  580. }
  581. test "GETRANGE against non-existing key" {
  582. r del mykey
  583. assert_equal "" [r getrange mykey 0 -1]
  584. }
  585. test "GETRANGE against string value" {
  586. r set mykey "Hello World"
  587. assert_equal "Hell" [r getrange mykey 0 3]
  588. assert_equal "Hello World" [r getrange mykey 0 -1]
  589. assert_equal "orld" [r getrange mykey -4 -1]
  590. assert_equal "" [r getrange mykey 5 3]
  591. assert_equal " World" [r getrange mykey 5 5000]
  592. assert_equal "Hello World" [r getrange mykey -5000 10000]
  593. }
  594. test "GETRANGE against integer-encoded value" {
  595. r set mykey 1234
  596. assert_equal "123" [r getrange mykey 0 2]
  597. assert_equal "1234" [r getrange mykey 0 -1]
  598. assert_equal "234" [r getrange mykey -3 -1]
  599. assert_equal "" [r getrange mykey 5 3]
  600. assert_equal "4" [r getrange mykey 3 5000]
  601. assert_equal "1234" [r getrange mykey -5000 10000]
  602. }
  603. test "GETRANGE fuzzing" {
  604. for {set i 0} {$i < 1000} {incr i} {
  605. r set bin [set bin [randstring 0 1024 binary]]
  606. set _start [set start [randomInt 1500]]
  607. set _end [set end [randomInt 1500]]
  608. if {$_start < 0} {set _start "end-[abs($_start)-1]"}
  609. if {$_end < 0} {set _end "end-[abs($_end)-1]"}
  610. assert_equal [string range $bin $_start $_end] [r getrange bin $start $end]
  611. }
  612. }
  613. test {Extended SET can detect syntax errors} {
  614. set e {}
  615. catch {r set foo bar non-existing-option} e
  616. set e
  617. } {*syntax*}
  618. test {Extended SET NX option} {
  619. r del foo
  620. set v1 [r set foo 1 nx]
  621. set v2 [r set foo 2 nx]
  622. list $v1 $v2 [r get foo]
  623. } {OK {} 1}
  624. test {Extended SET XX option} {
  625. r del foo
  626. set v1 [r set foo 1 xx]
  627. r set foo bar
  628. set v2 [r set foo 2 xx]
  629. list $v1 $v2 [r get foo]
  630. } {{} OK 2}
  631. test {Extended SET EX option} {
  632. r del foo
  633. r set foo bar ex 10
  634. set ttl [r ttl foo]
  635. assert {$ttl <= 10 && $ttl > 5}
  636. }
  637. test {Extended SET PX option} {
  638. r del foo
  639. r set foo bar px 10000
  640. set ttl [r ttl foo]
  641. assert {$ttl <= 10 && $ttl > 5}
  642. }
  643. test {Extended SET using multiple options at once} {
  644. r set foo val
  645. assert {[r set foo bar xx px 10000] eq {OK}}
  646. set ttl [r ttl foo]
  647. assert {$ttl <= 10 && $ttl > 5}
  648. }
  649. test {KEYS * two times with long key, Github issue #1208} {
  650. r flushdb
  651. r set dlskeriewrioeuwqoirueioqwrueoqwrueqw test
  652. r keys *
  653. r keys *
  654. } {dlskeriewrioeuwqoirueioqwrueoqwrueqw}
  655. }