예제 #1
0
class TubFailures(ExamineFailuresMixin, ShouldFailMixin, unittest.TestCase):
    def setUp(self):
        self.s = service.MultiService()
        self.s.startService()
        self.target_tub = UnauthenticatedTub()
        self.target_tub.setServiceParent(self.s)
        l = self.target_tub.listenOn("tcp:0:interface=127.0.0.1")
        self.target_tub.setLocation("127.0.0.1:%d" % l.getPortnum())
        self.source_tub = UnauthenticatedTub()
        self.source_tub.setServiceParent(self.s)

    def tearDown(self):
        return self.s.stopService()

    def setupTarget(self, target):
        furl = self.target_tub.registerReference(target)
        d = self.source_tub.getReference(furl)
        return d


    def test_raise_not_exposed(self):
        self.source_tub.setOption("expose-remote-exception-types", False)
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr:
                      self.shouldFail(RemoteException, "one", None,
                                      rr.callRemote, "fail"))
        d.addCallback(self._examine_raise, True)
        return d

    def test_raise_yes_exposed(self):
        self.source_tub.setOption("expose-remote-exception-types", True)
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr:
                      self.shouldFail(ValueError, "one", None,
                                      rr.callRemote, "fail"))
        d.addCallback(self._examine_raise, False)
        return d

    def test_raise_default(self):
        # current default is to expose exceptions. This may change in the
        # future.
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr:
                      self.shouldFail(ValueError, "one", None,
                                      rr.callRemote, "fail"))
        d.addCallback(self._examine_raise, False)
        return d
예제 #2
0
class ReferenceCounting(ShouldFailMixin, unittest.TestCase):
    def setUp(self):
        self.s = service.MultiService()
        self.s.startService()
        self.target_tub = UnauthenticatedTub()
        self.target_tub.setServiceParent(self.s)
        l = self.target_tub.listenOn("tcp:0:interface=127.0.0.1")
        self.target_tub.setLocation("127.0.0.1:%d" % l.getPortnum())
        self.source_tub = UnauthenticatedTub()
        self.source_tub.setServiceParent(self.s)

    def tearDown(self):
        return self.s.stopService()

    def setupTarget(self, target):
        furl = self.target_tub.registerReference(target)
        d = self.source_tub.getReference(furl)
        return d

    def test_reference_counting(self):
        self.source_tub.setOption("expose-remote-exception-types", True)
        target = HelperTarget()
        d = self.setupTarget(target)
        def _stash(rref):
            # to exercise bug #104, we need to trigger remote Violations, so
            # we tell the sending side to not use a RemoteInterface. We do
            # this by reaching inside the RemoteReference and making it
            # forget
            rref.tracker.interfaceName = None
            rref.tracker.interface = None
            self.rref = rref
        d.addCallback(_stash)

        # the first call causes an error, which discards all remaining
        # tokens, including the OPEN tokens for the arguments. The #104 bug
        # is that this causes the open-count to get out of sync, by -2 (one
        # for the arguments sequence, one for the list inside it).
        d.addCallback(lambda ign:
                      self.shouldFail(Violation, "one", None,
                                      self.rref.callRemote, "bogus",
                                      ["one list"]))

        #d.addCallback(lambda ign:
        #              self.rref.callRemote("set", ["one list"]))

        # a method call that has no arguments (specifically no REFERENCE
        # sequences) won't notice the loss of sync
        d.addCallback(lambda ign: self.rref.callRemote("set", 42))
        def _check_42(ign):
            self.failUnlessEqual(target.obj, 42)
        d.addCallback(_check_42)
        # but when the call takes shared arguments, sync matters
        l = ["list", 1, 2]
        s = set([3,4])
        t = ("tuple", 5, 6)
        d.addCallback(lambda ign: self.rref.callRemote("set", [t, l, s, t]))
        def _check_shared(ign):
            # the off-by-two bug would cause the second tuple shared-ref to
            # point at the set instead of the first tuple
            self.failUnlessEqual(type(target.obj), list)
            one, two, three, four = target.obj
            self.failUnlessEqual(type(one), tuple)
            self.failUnlessEqual(one, t)
            self.failUnlessEqual(type(two), list)
            self.failUnlessEqual(two, l)
            self.failUnlessEqual(type(three), set)
            self.failUnlessEqual(three, s)
            self.failUnlessEqual(type(four), tuple) # this is where it fails
            self.failUnlessEqual(four, t)
            self.failUnlessIdentical(one, four)
        d.addCallback(_check_shared)
        return d