]>
Commit | Line | Data |
---|---|---|
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 | } |