1start_server {tags {"scripting"}} { 2 test {EVAL - Does Lua interpreter replies to our requests?} { 3 r eval {return 'hello'} 0 4 } {hello} 5 6 test {EVAL - Lua integer -> Redis protocol type conversion} { 7 r eval {return 100.5} 0 8 } {100} 9 10 test {EVAL - Lua string -> Redis protocol type conversion} { 11 r eval {return 'hello world'} 0 12 } {hello world} 13 14 test {EVAL - Lua true boolean -> Redis protocol type conversion} { 15 r eval {return true} 0 16 } {1} 17 18 test {EVAL - Lua false boolean -> Redis protocol type conversion} { 19 r eval {return false} 0 20 } {} 21 22 test {EVAL - Lua status code reply -> Redis protocol type conversion} { 23 r eval {return {ok='fine'}} 0 24 } {fine} 25 26 test {EVAL - Lua error reply -> Redis protocol type conversion} { 27 catch { 28 r eval {return {err='this is an error'}} 0 29 } e 30 set _ $e 31 } {this is an error} 32 33 test {EVAL - Lua table -> Redis protocol type conversion} { 34 r eval {return {1,2,3,'ciao',{1,2}}} 0 35 } {1 2 3 ciao {1 2}} 36 37 test {EVAL - Are the KEYS and ARGS arrays populated correctly?} { 38 r eval {return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}} 2 a b c d 39 } {a b c d} 40 41 test {EVAL - is Lua able to call Redis API?} { 42 r set mykey myval 43 r eval {return redis.call('get','mykey')} 0 44 } {myval} 45 46 test {EVALSHA - Can we call a SHA1 if already defined?} { 47 r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0 48 } {myval} 49 50 test {EVALSHA - Do we get an error on invalid SHA1?} { 51 catch {r evalsha NotValidShaSUM 0} e 52 set _ $e 53 } {NOSCRIPT*} 54 55 test {EVALSHA - Do we get an error on non defined SHA1?} { 56 catch {r evalsha ffd632c7d33e571e9f24556ebed26c3479a87130 0} e 57 set _ $e 58 } {NOSCRIPT*} 59 60 test {EVAL - Redis integer -> Lua type conversion} { 61 r eval { 62 local foo = redis.pcall('incr','x') 63 return {type(foo),foo} 64 } 0 65 } {number 1} 66 67 test {EVAL - Redis bulk -> Lua type conversion} { 68 r set mykey myval 69 r eval { 70 local foo = redis.pcall('get','mykey') 71 return {type(foo),foo} 72 } 0 73 } {string myval} 74 75 test {EVAL - Redis multi bulk -> Lua type conversion} { 76 r del mylist 77 r rpush mylist a 78 r rpush mylist b 79 r rpush mylist c 80 r eval { 81 local foo = redis.pcall('lrange','mylist',0,-1) 82 return {type(foo),foo[1],foo[2],foo[3],# foo} 83 } 0 84 } {table a b c 3} 85 86 test {EVAL - Redis status reply -> Lua type conversion} { 87 r eval { 88 local foo = redis.pcall('set','mykey','myval') 89 return {type(foo),foo['ok']} 90 } 0 91 } {table OK} 92 93 test {EVAL - Redis error reply -> Lua type conversion} { 94 r set mykey myval 95 r eval { 96 local foo = redis.pcall('incr','mykey') 97 return {type(foo),foo['err']} 98 } 0 99 } {table {ERR value is not an integer or out of range}} 100 101 test {EVAL - Redis nil bulk reply -> Lua type conversion} { 102 r del mykey 103 r eval { 104 local foo = redis.pcall('get','mykey') 105 return {type(foo),foo == false} 106 } 0 107 } {boolean 1} 108 109 test {EVAL - Is Lua affecting the currently selected DB?} { 110 r set mykey "this is DB 9" 111 r select 10 112 r set mykey "this is DB 10" 113 r eval {return redis.pcall('get','mykey')} 0 114 } {this is DB 10} 115 116 test {EVAL - Is Lua seleced DB retained?} { 117 r eval {return redis.pcall('select','9')} 0 118 r get mykey 119 } {this is DB 9} 120 121 if 0 { 122 test {EVAL - Script can't run more than configured time limit} { 123 r config set lua-time-limit 1 124 catch { 125 r eval { 126 local i = 0 127 while true do i=i+1 end 128 } 0 129 } e 130 set _ $e 131 } {*execution time*} 132 } 133 134 test {EVAL - Scripts can't run certain commands} { 135 set e {} 136 catch {r eval {return redis.pcall('spop','x')} 0} e 137 set e 138 } {*not allowed*} 139 140 test {EVAL - Scripts can't run certain commands} { 141 set e {} 142 catch { 143 r eval "redis.pcall('randomkey'); return redis.pcall('set','x','ciao')" 0 144 } e 145 set e 146 } {*not allowed after*} 147 148 test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} { 149 set e {} 150 catch { 151 r eval "redis.call('nosuchcommand')" 0 152 } e 153 set e 154 } {*Unknown Redis*} 155 156 test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} { 157 set e {} 158 catch { 159 r eval "redis.call('get','a','b','c')" 0 160 } e 161 set e 162 } {*number of args*} 163 164 test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} { 165 set e {} 166 r set foo bar 167 catch { 168 r eval "redis.call('lpush','foo','val')" 0 169 } e 170 set e 171 } {*against a key*} 172 173 test {SCRIPTING FLUSH - is able to clear the scripts cache?} { 174 r set mykey myval 175 set v [r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0] 176 assert_equal $v myval 177 set e "" 178 r script flush 179 catch {r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0} e 180 set e 181 } {NOSCRIPT*} 182 183 test {SCRIPT EXISTS - can detect already defined scripts?} { 184 r eval "return 1+1" 0 185 r script exists a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bd9 a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bda 186 } {1 0} 187 188 test {SCRIPT LOAD - is able to register scripts in the scripting cache} { 189 list \ 190 [r script load "return 'loaded'"] \ 191 [r evalsha b534286061d4b9e4026607613b95c06c06015ae8 0] 192 } {b534286061d4b9e4026607613b95c06c06015ae8 loaded} 193 194 test "In the context of Lua the output of random commands gets ordered" { 195 r del myset 196 r sadd myset a b c d e f g h i l m n o p q r s t u v z aa aaa azz 197 r eval {return redis.call('smembers','myset')} 0 198 } {a aa aaa azz b c d e f g h i l m n o p q r s t u v z} 199 200 test "SORT is normally not re-ordered by the scripting engine" { 201 r del myset 202 r sadd myset 1 2 3 4 10 203 r eval {return redis.call('sort','myset','desc')} 0 204 } {10 4 3 2 1} 205 206 test "SORT BY <constant> output gets ordered by scripting" { 207 r del myset 208 r sadd myset a b c d e f g h i l m n o p q r s t u v z aa aaa azz 209 r eval {return redis.call('sort','myset','by','_')} 0 210 } {a aa aaa azz b c d e f g h i l m n o p q r s t u v z} 211 212 test "SORT output containing NULLs is well handled by scripting" { 213 r del myset 214 r sadd myset a b c 215 r eval {return redis.call('sort','myset','by','_','get','#','get','_:*')} 0 216 } {{} {} {} a b c} 217 218 test "redis.sha1hex() implementation" { 219 list [r eval {return redis.sha1hex('')} 0] \ 220 [r eval {return redis.sha1hex('Pizza & Mandolino')} 0] 221 } {da39a3ee5e6b4b0d3255bfef95601890afd80709 74822d82031af7493c20eefa13bd07ec4fada82f} 222} 223 224start_server {tags {"scripting repl"}} { 225 start_server {} { 226 test {Before the slave connects we issue an EVAL command} { 227 r eval {return redis.call('incr','x')} 0 228 } {1} 229 230 test {Connect a slave to the main instance} { 231 r -1 slaveof [srv 0 host] [srv 0 port] 232 after 1000 233 s -1 role 234 } {slave} 235 236 test {Now use EVALSHA against the master} { 237 r evalsha ae3477e27be955de7e1bc9adfdca626b478d3cb2 0 238 } {2} 239 240 if {$::valgrind} {after 2000} else {after 100} 241 242 test {If EVALSHA was replicated as EVAL the slave should be ok} { 243 r -1 get x 244 } {2} 245 } 246} 247