1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # See the COPYING file for license information.
17 # Copyright (c) 2007, 2008 Guillaume Chazarain <guichaz@gmail.com>
22 from gsh_tests
import launch_gsh
24 class TestControlCommands(unittest
.TestCase
):
25 def testControl(self
):
26 child
= launch_gsh(['localhost'])
27 child
.expect('ready \(1\)> ')
29 child
.expect('ready \(1\)> ')
30 child
.sendline('echo a; echo; echo; echo; echo; echo; echo; echo b')
33 child
.expect('ready \(1\)> ')
34 child
.sendline(':unknown')
35 child
.expect('Unknown control command: unknown')
36 child
.expect('ready \(1\)> ')
38 child
.expect('waiting \(1/1\)> ')
39 child
.sendline(':send_ctrl \tz\t\t')
40 child
.expect('ready \(1\)> ')
41 child
.sendline(':send_ctrl')
42 child
.expect('Expected at least a letter')
43 child
.expect('ready \(1\)> ')
44 child
.sendline(':send_ctrl word')
45 child
.expect('Expected a single letter, got: word')
46 child
.expect('ready \(1\)> ')
48 child
.expect('waiting \(1/1\)> ')
49 child
.sendcontrol('z')
50 child
.expect('ready \(1\)> ')
52 child
.expect('waiting \(1/1\)> ')
53 child
.sendline(':send_ctrl d')
54 child
.expect('ready \(1\)> ')
55 child
.sendline('sleep 1h')
56 child
.expect('waiting \(1/1\)> ')
57 child
.sendcontrol('c')
58 child
.expect('ready \(1\)> ')
60 child
.expect('waiting \(1/1\)> ')
61 child
.sendcontrol('d')
62 child
.expect('ready \(1\)> ')
64 child
.expect('waiting \(1/1\)> ')
65 child
.sendline(':disabl\tlocal* not_found\t')
66 child
.expect('not_found not found\r\n')
67 child
.expect('ready \(0\)> ')
68 child
.sendline(':help')
69 child
.expect(':enable')
70 child
.expect('ready \(0\)> ')
71 child
.sendline(':help repl\t')
72 child
.expect(':replicate')
73 child
.expect('ready \(0\)> ')
74 child
.sendline(':help :upl\t')
75 child
.expect(':upload')
76 child
.expect('ready \(0\)> ')
77 child
.sendline(':help badcommandname\t')
78 child
.expect('Unknown control command: badcommandname')
79 child
.expect('ready \(0\)> ')
80 child
.sendline(':enable local\t')
81 child
.expect('waiting \(1/1\)> ')
82 child
.sendline(':list')
83 child
.expect('localhost enabled running:')
84 child
.expect('waiting \(1/1\)> ')
85 child
.sendline(':list local\t')
86 child
.expect('localhost enabled running:')
87 child
.expect('waiting \(1/1\)> ')
88 child
.sendline(':list unknown')
89 child
.expect('unknown not found')
90 child
.expect('waiting \(1/1\)> ')
91 child
.sendline(':send_ctrl c')
92 child
.expect('ready \(1\)> ')
93 child
.sendline(':quit')
94 child
.expect(pexpect
.EOF
)
96 def testReconnect(self
):
97 child
= launch_gsh(['localhost'] * 2)
98 child
.expect('ready \(2\)> ')
99 child
.sendline(':disable localhost')
100 child
.sendline('exit')
101 child
.expect('Error talking to localhost#1\r\n')
102 child
.expect('ready \(0\)>')
103 child
.sendline(':reconnect l\t')
104 child
.sendline(':enable')
105 child
.expect('ready \(2\)> ')
107 child
.expect(pexpect
.EOF
)
109 def testListManipulation(self
):
110 child
= launch_gsh(['localhost'])
111 child
.expect('ready \(1\)> ')
112 child
.sendline(':add localhost')
113 child
.expect('ready \(2\)> ')
114 child
.sendline(':rename $(echo newname)')
115 child
.expect('ready \(2\)> ')
116 child
.sendline('date')
117 child
.expect('newname')
118 child
.expect('newname')
119 child
.expect('ready \(2\)> ')
120 child
.sendline(':rename $EMPTY_VARIABLE')
121 child
.expect('ready \(2\)> ')
122 child
.sendline('date')
123 child
.expect('localhost')
124 child
.expect('localhost')
125 child
.expect('ready \(2\)> ')
126 child
.sendline(':rename $(echo newname)')
127 child
.expect('ready \(2\)> ')
128 child
.sendline('date')
129 child
.expect('newname')
130 child
.expect('newname')
131 child
.expect('ready \(2\)> ')
132 child
.sendline(':disable newname')
133 child
.sendline(':purge')
134 child
.sendline(':enable *')
135 child
.expect('ready \(1\)> ')
136 child
.sendline(':rename')
137 child
.expect('ready \(1\)> ')
138 child
.sendline('date')
139 child
.expect('localhost:')
140 child
.expect('ready \(1\)> ')
142 child
.expect(pexpect
.EOF
)
144 def testLocalCommand(self
):
145 child
= launch_gsh(['localhost'])
146 child
.expect('ready \(1\)> ')
147 child
.sendline('cat')
148 child
.expect('waiting \(1/1\)> ')
149 child
.sendline('!ech\t te""st')
151 child
.sendline(':send_ctrl d')
152 child
.expect('ready \(1\)> ')
153 child
.sendline('!exit 42')
154 child
.expect('Child returned 42')
155 child
.expect('ready \(1\)> ')
156 child
.sendline('!python -c "import os; os.kill(os.getpid(), 9)"')
157 child
.expect('Child was terminated by signal 9')
158 child
.expect('ready \(1\)> ')
159 child
.sendline(':chdir /does/not/exist')
160 child
.expect("\[Errno 2\] .*: '/does/not/exist'")
161 child
.sendline(':chdir /usr/sbi\t/does/not/exist')
162 child
.expect('/usr/sbin')
163 child
.expect('ready \(1\)> ')
165 child
.expect(pexpect
.EOF
)
167 def testLocalAbsPathCompletion(self
):
168 child
= launch_gsh(['localhost'])
169 child
.expect('ready \(1\)> ')
170 child
.sendline('echo /dev/nul\t')
171 child
.expect('localhost: /dev/null')
172 child
.expect('ready \(1\)> ')
173 child
.sendline('echo /sbi\t')
174 child
.expect('localhost: /sbin/')
176 child
.expect(pexpect
.EOF
)
178 def testLogOutput(self
):
179 child
= launch_gsh(['--log-file=/', 'localhost'])
180 child
.expect("\[Errno 21\].*'/'")
181 child
.expect(pexpect
.EOF
)
182 child
= launch_gsh(['--log-file=/cannot_write', 'localhost'])
183 child
.expect("\[Errno 13\].*'/cannot_write'")
184 child
.expect(pexpect
.EOF
)
185 child
= launch_gsh(['--log-file=/dev/full', 'localhost'])
186 child
.expect('ready \(1\)> ')
187 child
.sendline('echo something')
188 child
.expect('Exception while writing log: /dev/full')
189 child
.expect('\[Errno 28\]')
190 child
.expect(pexpect
.EOF
)
192 child
= launch_gsh(['localhost'])
194 child
.expect('ready \(1\)> ')
195 child
.sendline('echo %s' % msg
)
196 child
.expect('localhost: %s' % msg
)
197 testEcho('not logging')
198 child
.sendline(':set_log')
199 testEcho('still not logging')
200 child
.sendline('!rm -f /tmp/gsh_test.log')
201 testEcho('still not logging')
202 child
.sendline(':set_log /tmp/gsh_test.log')
203 testEcho('now logging')
204 testEcho('still logging')
205 child
.sendline(':set_log')
206 testEcho('back to no logging')
207 child
.sendline(':set_log /tmp/gsh_test.lo\t')
208 testEcho('appended to the log')
209 child
.sendline(':set_log')
210 child
.expect('ready \(1\)> ')
211 child
.sendline(':set_log /no-permission')
212 child
.expect("[Errno 13] .*: '/no-permission'")
213 child
.expect('Logging disabled')
214 child
.expect('ready \(1\)> ')
216 child
.expect(pexpect
.EOF
)
220 localhost: now logging
222 localhost: still logging
224 > echo appended to the log
225 localhost: appended to the log
228 log
= file('/tmp/gsh_test.log')
229 log_lines
= [l
for l
in log
.readlines() if not l
.startswith('[dbg] ')]
230 actual_log
= ''.join(log_lines
).strip()
231 self
.assertEqual(actual_log
, EXPECTED_LOG
)
232 os
.remove('/tmp/gsh_test.log')
234 def testSetDebug(self
):
235 child
= launch_gsh(['localhost'])
236 child
.expect('ready \(1\)> ')
237 child
.sendline(':set_debug')
238 child
.expect('Expected at least a letter')
239 child
.sendline(':set_debug word')
240 child
.expect("Expected 'y' or 'n', got: word")
241 child
.sendline(':set_debug \ty\t\t')
242 child
.expect('ready \(1\)> ')
243 child
.sendline('echo "te""st"')
244 child
.expect('\[dbg\] localhost\[idle\]: state => running')
245 child
.expect('\[dbg\] localhost\[running\]: <== echo "te""st"')
246 child
.expect('\[dbg\] localhost\[running\]: ==> test')
247 child
.expect('localhost: test')
248 child
.expect('\[dbg\] localhost\[running\]: state => idle')
249 child
.expect('ready \(1\)> ')
251 child
.expect(pexpect
.EOF
)
253 def testHidePassword(self
):
254 child
= launch_gsh(['localhost'])
255 child
.expect('ready \(1\)> ')
256 child
.sendline('# passwordnotprotected')
257 child
.expect('ready \(1\)> ')
258 child
.sendline(':set_debug y')
259 child
.sendline(':set_log /dev/nul\t')
260 child
.sendline(':hide_password')
261 child
.expect('Debugging disabled')
262 child
.expect('Logging disabled')
263 child
.expect('ready \(1\)> ')
264 child
.sendline('# passwordprotected')
265 child
.expect('ready \(1\)> ')
266 child
.sendline('echo password\t')
267 child
.expect('passwordnotprotected')
268 child
.expect('ready \(1\)> ')
270 child
.expect(pexpect
.EOF
)
272 def testResetPrompt(self
):
273 child
= launch_gsh(['localhost'])
274 child
.expect('ready \(1\)> ')
275 child
.sendline('bash')
276 child
.sendline(':reset_prompt l\t')
277 child
.expect('ready \(1\)> ')
278 child
.sendline(':quit')
279 child
.expect(pexpect
.EOF
)
282 child
= launch_gsh(['localhost'] * 3)
283 child
.expect('ready \(3\)> ')
284 child
.sendline(':disable localhost#*')
285 child
.expect('ready \(1\)> ')
286 child
.sendline('kill -9 $$')
287 child
.expect('ready \(0\)> ')
288 child
.sendline(':enable')
289 child
.expect('ready \(2\)> ')
290 child
.sendline(':pur\t\t')
291 child
.expect('ready \(2\)> ')
292 child
.sendline(':list')
293 child
.expect('localhost#1 enabled idle:')
294 child
.expect('localhost#2 enabled idle:')
295 child
.expect('ready \(2\)> ')
297 child
.expect(pexpect
.EOF
)
299 def testPrintReadBuffer(self
):
300 child
= launch_gsh(['--ssh=echo message; sleep'] + ['1h'] * 3)
301 child
.expect('waiting \(3/3\)> ')
302 child
.sendline(':print_read_buffer \t*')
304 child
.expect('1h[ #][ 12]: message')
305 child
.expect('waiting \(3/3\)> ')
306 child
.sendline(':quit')
307 child
.expect(pexpect
.EOF
)