]>
Commit | Line | Data |
---|---|---|
f2dd4769 PN |
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 | ||
f9b25261 | 31 | # Helpers to run tests in interactive mode |
f2dd4769 PN |
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} { | |
ae77016e | 40 | set ::env(FAKETTY) 1 |
f2dd4769 PN |
41 | set fd [open_cli] |
42 | test "Interactive CLI: $name" $code | |
43 | close_cli $fd | |
ae77016e | 44 | unset ::env(FAKETTY) |
f2dd4769 PN |
45 | } |
46 | ||
f9b25261 | 47 | # Helpers to run tests where stdout is not a tty |
b4b62c34 PN |
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"] | |
07242c0c PN |
68 | fconfigure $fd -buffering none |
69 | fconfigure $fd -translation binary | |
70 | set resp [read $fd 1048576] | |
71 | close $fd | |
72 | set _ $resp | |
73 | } | |
74 | ||
b4b62c34 PN |
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 | ||
123a10f7 PN |
87 | proc test_nontty_cli {name code} { |
88 | test "Non-interactive non-TTY CLI: $name" $code | |
89 | } | |
90 | ||
f791d66e | 91 | # Helpers to run tests where stdout is a tty (fake it) |
123a10f7 | 92 | proc test_tty_cli {name code} { |
f791d66e | 93 | set ::env(FAKETTY) 1 |
123a10f7 | 94 | test "Non-interactive TTY CLI: $name" $code |
f791d66e | 95 | unset ::env(FAKETTY) |
07242c0c PN |
96 | } |
97 | ||
f2dd4769 PN |
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 | } | |
0439d792 PN |
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 | } | |
07242c0c | 142 | |
123a10f7 | 143 | test_tty_cli "Status reply" { |
f791d66e | 144 | assert_equal "OK\n" [run_cli set key bar] |
07242c0c PN |
145 | assert_equal "bar" [r get key] |
146 | } | |
147 | ||
123a10f7 | 148 | test_tty_cli "Integer reply" { |
07242c0c | 149 | r del counter |
f791d66e | 150 | assert_equal "(integer) 1\n" [run_cli incr counter] |
07242c0c PN |
151 | } |
152 | ||
123a10f7 | 153 | test_tty_cli "Bulk reply" { |
07242c0c | 154 | r set key "tab\tnewline\n" |
f791d66e | 155 | assert_equal "\"tab\\tnewline\\n\"\n" [run_cli get key] |
07242c0c PN |
156 | } |
157 | ||
123a10f7 | 158 | test_tty_cli "Multi-bulk reply" { |
07242c0c PN |
159 | r del list |
160 | r rpush list foo | |
161 | r rpush list bar | |
f791d66e | 162 | assert_equal "1. \"foo\"\n2. \"bar\"\n" [run_cli lrange list 0 -1] |
07242c0c | 163 | } |
3a51bff0 | 164 | |
b4b62c34 PN |
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 | ||
3a51bff0 | 176 | test_nontty_cli "Status reply" { |
f791d66e | 177 | assert_equal "OK" [run_cli set key bar] |
3a51bff0 PN |
178 | assert_equal "bar" [r get key] |
179 | } | |
180 | ||
181 | test_nontty_cli "Integer reply" { | |
182 | r del counter | |
f791d66e | 183 | assert_equal "1" [run_cli incr counter] |
3a51bff0 PN |
184 | } |
185 | ||
186 | test_nontty_cli "Bulk reply" { | |
187 | r set key "tab\tnewline\n" | |
f791d66e | 188 | assert_equal "tab\tnewline\n" [run_cli get key] |
3a51bff0 PN |
189 | } |
190 | ||
191 | test_nontty_cli "Multi-bulk reply" { | |
192 | r del list | |
193 | r rpush list foo | |
194 | r rpush list bar | |
f791d66e | 195 | assert_equal "foo\nbar" [run_cli lrange list 0 -1] |
3a51bff0 | 196 | } |
b4b62c34 PN |
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 | } | |
f2dd4769 | 208 | } |