]> git.saurik.com Git - redis.git/blob - tests/integration/redis-cli.tcl
Merge pull request #414 from chobits/unstable
[redis.git] / tests / integration / redis-cli.tcl
1 start_server {tags {"cli"}} {
2 proc open_cli {} {
3 set ::env(TERM) dumb
4 set fd [open [format "|src/redis-cli -p %d -n 9" [srv port]] "r+"]
5 fconfigure $fd -buffering none
6 fconfigure $fd -blocking false
7 fconfigure $fd -translation binary
8 assert_equal "redis> " [read_cli $fd]
9 set _ $fd
10 }
11
12 proc close_cli {fd} {
13 close $fd
14 }
15
16 proc read_cli {fd} {
17 set buf [read $fd]
18 while {[string length $buf] == 0} {
19 # wait some time and try again
20 after 10
21 set buf [read $fd]
22 }
23 set _ $buf
24 }
25
26 proc write_cli {fd buf} {
27 puts $fd $buf
28 flush $fd
29 }
30
31 # Helpers to run tests in interactive mode
32 proc run_command {fd cmd} {
33 write_cli $fd $cmd
34 set lines [split [read_cli $fd] "\n"]
35 assert_equal "redis> " [lindex $lines end]
36 join [lrange $lines 0 end-1] "\n"
37 }
38
39 proc test_interactive_cli {name code} {
40 set ::env(FAKETTY) 1
41 set fd [open_cli]
42 test "Interactive CLI: $name" $code
43 close_cli $fd
44 unset ::env(FAKETTY)
45 }
46
47 # Helpers to run tests where stdout is not a tty
48 proc write_tmpfile {contents} {
49 set tmp [tmpfile "cli"]
50 set tmpfd [open $tmp "w"]
51 puts -nonewline $tmpfd $contents
52 close $tmpfd
53 set _ $tmp
54 }
55
56 proc _run_cli {opts args} {
57 set cmd [format "src/redis-cli -p %d -n 9 $args" [srv port]]
58 foreach {key value} $opts {
59 if {$key eq "pipe"} {
60 set cmd "sh -c \"$value | $cmd\""
61 }
62 if {$key eq "path"} {
63 set cmd "$cmd < $value"
64 }
65 }
66
67 set fd [open "|$cmd" "r"]
68 fconfigure $fd -buffering none
69 fconfigure $fd -translation binary
70 set resp [read $fd 1048576]
71 close $fd
72 set _ $resp
73 }
74
75 proc run_cli {args} {
76 _run_cli {} {*}$args
77 }
78
79 proc run_cli_with_input_pipe {cmd args} {
80 _run_cli [list pipe $cmd] {*}$args
81 }
82
83 proc run_cli_with_input_file {path args} {
84 _run_cli [list path $path] {*}$args
85 }
86
87 proc test_nontty_cli {name code} {
88 test "Non-interactive non-TTY CLI: $name" $code
89 }
90
91 # Helpers to run tests where stdout is a tty (fake it)
92 proc test_tty_cli {name code} {
93 set ::env(FAKETTY) 1
94 test "Non-interactive TTY CLI: $name" $code
95 unset ::env(FAKETTY)
96 }
97
98 test_interactive_cli "INFO response should be printed raw" {
99 set lines [split [run_command $fd info] "\n"]
100 foreach line $lines {
101 assert [regexp {^[a-z0-9_]+:[a-z0-9_]+} $line]
102 }
103 }
104
105 test_interactive_cli "Status reply" {
106 assert_equal "OK" [run_command $fd "set key foo"]
107 }
108
109 test_interactive_cli "Integer reply" {
110 assert_equal "(integer) 1" [run_command $fd "incr counter"]
111 }
112
113 test_interactive_cli "Bulk reply" {
114 r set key foo
115 assert_equal "\"foo\"" [run_command $fd "get key"]
116 }
117
118 test_interactive_cli "Multi-bulk reply" {
119 r rpush list foo
120 r rpush list bar
121 assert_equal "1. \"foo\"\n2. \"bar\"" [run_command $fd "lrange list 0 -1"]
122 }
123
124 test_interactive_cli "Parsing quotes" {
125 assert_equal "OK" [run_command $fd "set key \"bar\""]
126 assert_equal "bar" [r get key]
127 assert_equal "OK" [run_command $fd "set key \" bar \""]
128 assert_equal " bar " [r get key]
129 assert_equal "OK" [run_command $fd "set key \"\\\"bar\\\"\""]
130 assert_equal "\"bar\"" [r get key]
131 assert_equal "OK" [run_command $fd "set key \"\tbar\t\""]
132 assert_equal "\tbar\t" [r get key]
133
134 # invalid quotation
135 assert_equal "Invalid argument(s)" [run_command $fd "get \"\"key"]
136 assert_equal "Invalid argument(s)" [run_command $fd "get \"key\"x"]
137
138 # quotes after the argument are weird, but should be allowed
139 assert_equal "OK" [run_command $fd "set key\"\" bar"]
140 assert_equal "bar" [r get key]
141 }
142
143 test_tty_cli "Status reply" {
144 assert_equal "OK\n" [run_cli set key bar]
145 assert_equal "bar" [r get key]
146 }
147
148 test_tty_cli "Integer reply" {
149 r del counter
150 assert_equal "(integer) 1\n" [run_cli incr counter]
151 }
152
153 test_tty_cli "Bulk reply" {
154 r set key "tab\tnewline\n"
155 assert_equal "\"tab\\tnewline\\n\"\n" [run_cli get key]
156 }
157
158 test_tty_cli "Multi-bulk reply" {
159 r del list
160 r rpush list foo
161 r rpush list bar
162 assert_equal "1. \"foo\"\n2. \"bar\"\n" [run_cli lrange list 0 -1]
163 }
164
165 test_tty_cli "Read last argument from pipe" {
166 assert_equal "OK\n" [run_cli_with_input_pipe "echo foo" set key]
167 assert_equal "foo\n" [r get key]
168 }
169
170 test_tty_cli "Read last argument from file" {
171 set tmpfile [write_tmpfile "from file"]
172 assert_equal "OK\n" [run_cli_with_input_file $tmpfile set key]
173 assert_equal "from file" [r get key]
174 }
175
176 test_nontty_cli "Status reply" {
177 assert_equal "OK" [run_cli set key bar]
178 assert_equal "bar" [r get key]
179 }
180
181 test_nontty_cli "Integer reply" {
182 r del counter
183 assert_equal "1" [run_cli incr counter]
184 }
185
186 test_nontty_cli "Bulk reply" {
187 r set key "tab\tnewline\n"
188 assert_equal "tab\tnewline\n" [run_cli get key]
189 }
190
191 test_nontty_cli "Multi-bulk reply" {
192 r del list
193 r rpush list foo
194 r rpush list bar
195 assert_equal "foo\nbar" [run_cli lrange list 0 -1]
196 }
197
198 test_nontty_cli "Read last argument from pipe" {
199 assert_equal "OK" [run_cli_with_input_pipe "echo foo" set key]
200 assert_equal "foo\n" [r get key]
201 }
202
203 test_nontty_cli "Read last argument from file" {
204 set tmpfile [write_tmpfile "from file"]
205 assert_equal "OK" [run_cli_with_input_file $tmpfile set key]
206 assert_equal "from file" [r get key]
207 }
208 }