]> git.saurik.com Git - redis.git/blob - tests/unit/scripting.tcl
Fixes for the scripting refactoring and new commands. Tests for the new features.
[redis.git] / tests / unit / scripting.tcl
1 start_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 test {EVAL - Script can't run more than configured time limit} {
122 r config set lua-time-limit 1
123 catch {
124 r eval {
125 local i = 0
126 while true do i=i+1 end
127 } 0
128 } e
129 set _ $e
130 } {*execution time*}
131
132 test {EVAL - Scripts can't run certain commands} {
133 set e {}
134 catch {r eval {return redis.pcall('spop','x')} 0} e
135 set e
136 } {*not allowed*}
137
138 test {EVAL - Scripts can't run certain commands} {
139 set e {}
140 catch {
141 r eval "redis.pcall('randomkey'); return redis.pcall('set','x','ciao')" 0
142 } e
143 set e
144 } {*not allowed after*}
145
146 test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} {
147 set e {}
148 catch {
149 r eval "redis.call('nosuchcommand')" 0
150 } e
151 set e
152 } {*Unknown Redis*}
153
154 test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} {
155 set e {}
156 catch {
157 r eval "redis.call('get','a','b','c')" 0
158 } e
159 set e
160 } {*number of args*}
161
162 test {EVAL - redis.call variant raises a Lua error on Redis cmd error (1)} {
163 set e {}
164 r set foo bar
165 catch {
166 r eval "redis.call('lpush','foo','val')" 0
167 } e
168 set e
169 } {*against a key*}
170
171 test {SCRIPTING FLUSH - is able to clear the scripts cache?} {
172 r set mykey myval
173 set v [r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0]
174 assert_equal $v myval
175 set e ""
176 r script flush
177 catch {r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0} e
178 set e
179 } {NOSCRIPT*}
180
181 test {SCRIPT EXISTS - can detect already defined scripts?} {
182 r eval "return 1+1" 0
183 r script exists a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bd9 a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bda
184 } {1 0}
185
186 test {SCRIPT LOAD - is able to register scripts in the scripting cache} {
187 list \
188 [r script load "return 'loaded'"] \
189 [r evalsha b534286061d4b9e4026607613b95c06c06015ae8 0]
190 } {OK loaded}
191 }
192
193 start_server {tags {"scripting repl"}} {
194 start_server {} {
195 test {Before the slave connects we issue an EVAL command} {
196 r eval {return redis.call('incr','x')} 0
197 } {1}
198
199 test {Connect a slave to the main instance} {
200 r -1 slaveof [srv 0 host] [srv 0 port]
201 after 1000
202 s -1 role
203 } {slave}
204
205 test {Now use EVALSHA against the master} {
206 r evalsha ae3477e27be955de7e1bc9adfdca626b478d3cb2 0
207 } {2}
208
209 if {$::valgrind} {after 2000} else {after 100}
210
211 test {If EVALSHA was replicated as EVAL the slave should be ok} {
212 r -1 get x
213 } {2}
214 }
215 }