1
# -*- test-case-name: twisted.conch.test.test_manhole -*-
2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3
# See LICENSE for details.
5
from __future__ import generators
9
from twisted.trial import unittest
10
from twisted.internet import error, defer
11
from twisted.conch.test.test_recvline import _TelnetMixin, _SSHMixin, _StdioMixin, stdio, ssh
12
from twisted.conch import manhole
14
def determineDefaultFunctionName():
16
Return the string used by Python as the name for code objects which are
17
compiled from interactive input or at the top-level of modules.
22
return traceback.extract_stack()[0][2]
23
defaultFunctionName = determineDefaultFunctionName()
26
class WriterTestCase(unittest.TestCase):
27
def testInteger(self):
28
manhole.lastColorizedLine("1")
31
def testDoubleQuoteString(self):
32
manhole.lastColorizedLine('"1"')
35
def testSingleQuoteString(self):
36
manhole.lastColorizedLine("'1'")
39
def testTripleSingleQuotedString(self):
40
manhole.lastColorizedLine("'''1'''")
43
def testTripleDoubleQuotedString(self):
44
manhole.lastColorizedLine('"""1"""')
47
def testFunctionDefinition(self):
48
manhole.lastColorizedLine("def foo():")
51
def testClassDefinition(self):
52
manhole.lastColorizedLine("class foo:")
55
class ManholeLoopbackMixin:
56
serverProtocol = manhole.ColoredManhole
59
return defer.waitForDeferred(d)
61
def testSimpleExpression(self):
62
done = self.recvlineClient.expect("done")
74
return done.addCallback(finished)
76
def testTripleQuoteLineContinuation(self):
77
done = self.recvlineClient.expect("done")
90
return done.addCallback(finished)
92
def testFunctionDefinition(self):
93
done = self.recvlineClient.expect("done")
103
[">>> def foo(bar):",
110
return done.addCallback(finished)
112
def testClassDefinition(self):
113
done = self.recvlineClient.expect("done")
118
"\t\tprint 'Hello, world!'\n\n"
125
"... def bar(self):",
126
"... print 'Hello, world!'",
132
return done.addCallback(finished)
134
def testException(self):
135
done = self.recvlineClient.expect("done")
144
"Traceback (most recent call last):",
145
' File "<console>", line 1, in ' + defaultFunctionName,
146
"ZeroDivisionError: integer division or modulo by zero",
149
return done.addCallback(finished)
151
def testControlC(self):
152
done = self.recvlineClient.expect("done")
155
"cancelled line" + manhole.CTRL_C +
160
[">>> cancelled line",
164
return done.addCallback(finished)
166
def testControlBackslash(self):
167
self._testwrite("cancelled line")
168
partialLine = self.recvlineClient.expect("cancelled line")
170
def gotPartialLine(ign):
172
[">>> cancelled line"])
173
self._testwrite(manhole.CTRL_BACKSLASH)
175
d = self.recvlineClient.onDisconnection
176
return self.assertFailure(d, error.ConnectionDone)
178
def gotClearedLine(ign):
182
return partialLine.addCallback(gotPartialLine).addCallback(gotClearedLine)
184
def testControlD(self):
185
self._testwrite("1 + 1")
186
helloWorld = self.wfd(self.recvlineClient.expect(r"\+ 1"))
188
helloWorld.getResult()
189
self._assertBuffer([">>> 1 + 1"])
191
self._testwrite(manhole.CTRL_D + " + 1")
192
cleared = self.wfd(self.recvlineClient.expect(r"\+ 1"))
195
self._assertBuffer([">>> 1 + 1 + 1"])
197
self._testwrite("\n")
198
printed = self.wfd(self.recvlineClient.expect("3\n>>> "))
202
self._testwrite(manhole.CTRL_D)
203
d = self.recvlineClient.onDisconnection
204
disconnected = self.wfd(self.assertFailure(d, error.ConnectionDone))
206
disconnected.getResult()
207
testControlD = defer.deferredGenerator(testControlD)
210
def testControlL(self):
212
CTRL+L is generally used as a redraw-screen command in terminal
213
applications. Manhole doesn't currently respect this usage of it,
214
but it should at least do something reasonable in response to this
215
event (rather than, say, eating your face).
217
# Start off with a newline so that when we clear the display we can
218
# tell by looking for the missing first empty prompt line.
219
self._testwrite("\n1 + 1")
220
helloWorld = self.wfd(self.recvlineClient.expect(r"\+ 1"))
222
helloWorld.getResult()
223
self._assertBuffer([">>> ", ">>> 1 + 1"])
225
self._testwrite(manhole.CTRL_L + " + 1")
226
redrew = self.wfd(self.recvlineClient.expect(r"1 \+ 1 \+ 1"))
229
self._assertBuffer([">>> 1 + 1 + 1"])
230
testControlL = defer.deferredGenerator(testControlL)
233
def testDeferred(self):
235
"from twisted.internet import defer, reactor\n"
236
"d = defer.Deferred()\n"
239
deferred = self.wfd(self.recvlineClient.expect("<Deferred #0>"))
244
"c = reactor.callLater(0.1, d.callback, 'Hi!')\n")
245
delayed = self.wfd(self.recvlineClient.expect(">>> "))
249
called = self.wfd(self.recvlineClient.expect("Deferred #0 called back: 'Hi!'\n>>> "))
253
[">>> from twisted.internet import defer, reactor",
254
">>> d = defer.Deferred()",
257
">>> c = reactor.callLater(0.1, d.callback, 'Hi!')",
258
"Deferred #0 called back: 'Hi!'",
261
testDeferred = defer.deferredGenerator(testDeferred)
263
class ManholeLoopbackTelnet(_TelnetMixin, unittest.TestCase, ManholeLoopbackMixin):
266
class ManholeLoopbackSSH(_SSHMixin, unittest.TestCase, ManholeLoopbackMixin):
268
skip = "Crypto requirements missing, can't run manhole tests over ssh"
270
class ManholeLoopbackStdio(_StdioMixin, unittest.TestCase, ManholeLoopbackMixin):
272
skip = "Terminal requirements missing, can't run manhole tests over stdio"
274
serverProtocol = stdio.ConsoleManhole