# Twisted, the Framework of Your Internet
# Copyright (C) 2001 Matthew W. Lefkowitz
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from twisted.trial import unittest
from twisted.spread import pb
from twisted.internet import reactor, defer
from twisted.python import log, failure
##
# test exceptions
##
class PoopError(Exception): pass
class FailError(Exception): pass
class DieError(Exception): pass
class TimeoutError(Exception): pass
####
# server-side
####
class SimpleRoot(pb.Root):
def remote_poop(self):
return defer.fail(failure.Failure(PoopError("Someone threw poopie at me!")))
def remote_fail(self):
raise FailError("I'm a complete failure! :(")
def remote_die(self):
raise DieError("*gack*")
class PBFailureTest(unittest.TestCase):
compare = unittest.TestCase.assertEquals
unsafeTracebacks = 0
def setUp(self):
self.results = [42000, 4200, 420, 42]
def testPBFailures(self):
factory = pb.PBServerFactory(SimpleRoot())
factory.unsafeTracebacks = self.unsafeTracebacks
p = reactor.listenTCP(0, factory, interface="127.0.0.1")
self.port = p.getHost()[2]
self.runClient()
reactor.run()
p.stopListening()
log.flushErrors(PoopError, FailError, DieError, AttributeError)
def runClient(self):
f = pb.PBClientFactory()
reactor.connectTCP("127.0.0.1", self.port, f)
f.getRootObject().addCallbacks(self.connected, self.notConnected)
self.id = reactor.callLater(10, self.timeOut)
def a(self, d):
for m in (self.failurePoop, self.failureFail, self.failureDie, self.failureNoSuch, lambda x: x):
d.addCallbacks(self.success, m)
def stopReactor(self):
self.id.cancel()
reactor.crash()
##
# callbacks
##
def connected(self, persp):
self.a(persp.callRemote('poop'))
self.a(persp.callRemote('fail'))
self.a(persp.callRemote('die'))
self.a(persp.callRemote("nosuch"))
def notConnected(self, fail):
self.stopReactor()
raise pb.Error("There's probably something wrong with your environment"
", because I couldn't connect to myself.")
def success(self, result):
if result == self.results[-1]:
self.results.pop()
if not self.results:
self.stopReactor()
def failurePoop(self, fail):
fail.trap(PoopError)
self.compare(fail.traceback, "Traceback unavailable\n")
return 42
def failureFail(self, fail):
fail.trap(FailError)
self.compare(fail.traceback, "Traceback unavailable\n")
return 420
def failureDie(self, fail):
fail.trap(DieError)
self.compare(fail.traceback, "Traceback unavailable\n")
return 4200
def failureNoSuch(self, fail):
# XXX maybe PB shouldn't send AttributeErrors? and make generic exception
# for no such method?
fail.trap(AttributeError)
self.compare(fail.traceback, "Traceback unavailable\n")
return 42000
def timeOut(self):
reactor.crash()
raise TimeoutError("Never got all three failures!")
class PBFailureTestUnsafe(PBFailureTest):
compare = unittest.TestCase.failIfEquals
unsafeTracebacks = 1
syntax highlighted by Code2HTML, v. 0.9.1