Example #1
0
 def testAccept2(self):
     req = TestRequest(12)
     req.setConstraint(schema.makeConstraint(str))
     self.broker.addRequest(req)
     u = self.newUnslicer()
     u.checkToken(INT, 0)
     u.receiveChild(12)  # causes broker.getRequest
     u.checkToken(STRING, 15)
     u.receiveChild("results")
     self.failIf(req.answers)
     u.receiveClose()  # causes broker.gotAnswer
     self.failUnlessEqual(req.answers, [(True, "results")])
Example #2
0
 def testAccept2(self):
     req = TestRequest(12)
     req.setConstraint(schema.makeConstraint(str))
     self.broker.addRequest(req)
     u = self.newUnslicer()
     u.checkToken(INT, 0)
     u.receiveChild(12) # causes broker.getRequest
     u.checkToken(STRING, 15)
     u.receiveChild("results")
     self.failIf(req.answers)
     u.receiveClose() # causes broker.gotAnswer
     self.failUnlessEqual(req.answers, [(True, "results")])
Example #3
0
 def testReject2(self):
     req = TestRequest(12)
     req.setConstraint(schema.makeConstraint(int))
     self.broker.addRequest(req)
     u = self.newUnslicer()
     u.checkToken(INT, 0)
     u.receiveChild(12)
     self.failUnlessRaises(Violation, u.checkToken, STRING, 42)
     self.failIf(req.answers)
     v = Violation("icky")
     v.setLocation("here")
     u.reportViolation(BananaFailure(v))
     self.failUnlessEqual(len(req.answers), 1)
     err = req.answers[0]
     self.failIf(err[0])
     f = err[1]
     self.failUnless(f.check(Violation))
Example #4
0
 def callRemote(self, _name, *args, **kwargs):
     req = None
     broker = self.tracker.broker
     methodConstraintOverride = kwargs.get("_methodConstraint", "none")
     resultConstraint = kwargs.get("_resultConstraint", "none")
     useSchema = kwargs.get("_useSchema", True)
     if "_methodConstraint" in kwargs:
         del kwargs["_methodConstraint"]
     if "_resultConstraint" in kwargs:
         del kwargs["_resultConstraint"]
     if "_useSchema" in kwargs:
         del kwargs["_useSchema"]
     try:
         reqID = broker.newRequestID()
     except:
         return defer.fail()
     try:
         req = call.PendingRequest(reqID, self)
         (methodName, methodSchema) = self._getMethodInfo(_name)
         req.methodName = methodName  # for debugging
         if methodConstraintOverride != "none":
             methodSchema = methodConstraintOverride
         if useSchema and methodSchema:
             argsdict = methodSchema.mapArguments(args, kwargs)
             methodSchema.checkAllArgs(kwargs)
             req.setConstraint(methodSchema.getResponseConstraint())
         else:
             if args:
                 why = "positional arguments require a RemoteInterface"
                 why += " for %s.%s()" % (self, methodName)
                 raise tokens.BananaError(why)
             argsdict = kwargs
         if resultConstraint != "none":
             req.setConstraint(schema.makeConstraint(resultConstraint))
     except:  # TODO: merge this with the next try/except clause
         req.fail(failure.Failure())
         return req.deferred
     try:
         self.tracker.broker.addRequest(req)
         slicer = call.CallSlicer(reqID, self.tracker.clid, methodName, argsdict)
         d = broker.send(slicer)
     except:
         req.fail(failure.Failure())
         return req.deferred
     d.addErrback(req.fail)
     return req.deferred
Example #5
0
 def testReject2(self):
     # answer a request with a result that violates the constraint
     req = TestRequest(12)
     req.setConstraint(schema.makeConstraint(int))
     self.broker.addRequest(req)
     u = self.newUnslicer()
     u.checkToken(INT, 0)
     u.receiveChild(12)
     self.failUnlessRaises(Violation, u.checkToken, STRING, 42)
     # this does not yet errback the request
     self.failIf(req.answers)
     # it gets errbacked when banana reports the violation
     v = Violation("icky")
     v.setLocation("here")
     u.reportViolation(BananaFailure(v))
     self.failUnlessEqual(len(req.answers), 1)
     err = req.answers[0]
     self.failIf(err[0])
     f = err[1]
     self.failUnless(f.check(Violation))
Example #6
0
 def testReject2(self):
     # answer a request with a result that violates the constraint
     req = TestRequest(12)
     req.setConstraint(schema.makeConstraint(int))
     self.broker.addRequest(req)
     u = self.newUnslicer()
     u.checkToken(INT, 0)
     u.receiveChild(12)
     self.failUnlessRaises(Violation, u.checkToken, STRING, 42)
     # this does not yet errback the request
     self.failIf(req.answers)
     # it gets errbacked when banana reports the violation
     v = Violation("icky")
     v.setLocation("here")
     u.reportViolation(BananaFailure(v))
     self.failUnlessEqual(len(req.answers), 1)
     err = req.answers[0]
     self.failIf(err[0])
     f = err[1]
     self.failUnless(f.check(Violation))
Example #7
0
    def callRemote(self, _name, *args, **kwargs):
        # Note: for consistency, *all* failures are reported asynchronously.

        req = None
        broker = self.tracker.broker

        # remember that "none" is not a valid constraint, so we use it to
        # mean "not set by the caller", which means we fall back to whatever
        # the RemoteInterface says. Using None would mean an AnyConstraint,
        # which is not the same thing.
        methodConstraintOverride = kwargs.get("_methodConstraint", "none")
        resultConstraint = kwargs.get("_resultConstraint", "none")
        useSchema = kwargs.get("_useSchema", True)

        if "_methodConstraint" in kwargs:
            del kwargs["_methodConstraint"]
        if "_resultConstraint" in kwargs:
            del kwargs["_resultConstraint"]
        if "_useSchema" in kwargs:
            del kwargs["_useSchema"]

        try:
            # newRequestID() could fail with a DeadReferenceError
            reqID = broker.newRequestID()
        except:
            return defer.fail()

        try:
            # in this clause, we validate the outbound arguments against our
            # notion of what the other end will accept (the RemoteInterface)
            req = call.PendingRequest(reqID, self)

            # first, figure out which method they want to invoke

            (methodName, methodSchema) = self._getMethodInfo(_name)
            req.methodName = methodName # for debugging
            if methodConstraintOverride != "none":
                methodSchema = methodConstraintOverride
            if useSchema and methodSchema:
                # turn positional arguments into kwargs. mapArguments() could
                # fail for bad argument names or missing required parameters
                argsdict = methodSchema.mapArguments(args, kwargs)

                # check args against the arg constraint. This could fail if
                # any arguments are of the wrong type
                methodSchema.checkAllArgs(kwargs)

                # the Interface gets to constraint the return value too, so
                # make a note of it to use later
                req.setConstraint(methodSchema.getResponseConstraint())
            else:
                if args:
                    why = "positional arguments require a RemoteInterface"
                    why += " for %s.%s()" % (self, methodName)
                    raise tokens.BananaError(why)
                argsdict = kwargs

            # if the caller specified a _resultConstraint, that overrides
            # the schema's one
            if resultConstraint != "none":
                # overrides schema
                req.setConstraint(schema.makeConstraint(resultConstraint))

        except: # TODO: merge this with the next try/except clause
            # we have not yet sent anything to the far end. A failure here
            # is entirely local: stale broker, bad method name, bad
            # arguments. We abandon the PendingRequest, but errback the
            # Deferred it was going to use
            req.fail(failure.Failure())
            return req.deferred

        try:
            # once we start sending the CallSlicer, we could get either a
            # local or a remote failure, so we must be prepared to accept an
            # answer. After this point, we assign all responsibility to the
            # PendingRequest structure.
            self.tracker.broker.addRequest(req)

            # TODO: there is a decidability problem here: if the reqID made
            # it through, the other end will send us an answer (possibly an
            # error if the remaining slices were aborted). If not, we will
            # not get an answer. To decide whether we should remove our
            # broker.waitingForAnswers[] entry, we need to know how far the
            # slicing process made it.

            slicer = call.CallSlicer(reqID, self.tracker.clid,
                                     methodName, argsdict)

            # this could fail if any of the arguments (or their children)
            # are unsliceable
            d = broker.send(slicer)
            # d will fire when the last argument has been serialized. It
            # will errback if the arguments could not be serialized. We need
            # to catch this case and errback the caller.

        except:
            req.fail(failure.Failure())
            return req.deferred

        # if we got here, we have been able to start serializing the
        # arguments. If serialization fails, the PendingRequest needs to be
        # flunked (because we aren't guaranteed that the far end will do it).

        d.addErrback(req.fail)

        # the remote end could send back an error response for many reasons:
        #  bad method name
        #  bad argument types (violated their schema)
        #  exception during method execution
        #  method result violated the results schema
        # something else could occur to cause an errback:
        #  connection lost before response completely received
        #  exception during deserialization of the response
        #   [but only if it occurs after the reqID is received]
        #  method result violated our results schema
        # if none of those occurred, the callback will be run

        return req.deferred
Example #8
0
    def callRemote(self, _name, *args, **kwargs):
        # Note: for consistency, *all* failures are reported asynchronously.

        req = None
        broker = self.tracker.broker

        # remember that "none" is not a valid constraint, so we use it to
        # mean "not set by the caller", which means we fall back to whatever
        # the RemoteInterface says. Using None would mean an AnyConstraint,
        # which is not the same thing.
        methodConstraintOverride = kwargs.get("_methodConstraint", "none")
        resultConstraint = kwargs.get("_resultConstraint", "none")
        useSchema = kwargs.get("_useSchema", True)

        if "_methodConstraint" in kwargs:
            del kwargs["_methodConstraint"]
        if "_resultConstraint" in kwargs:
            del kwargs["_resultConstraint"]
        if "_useSchema" in kwargs:
            del kwargs["_useSchema"]

        try:
            # newRequestID() could fail with a DeadReferenceError
            reqID = broker.newRequestID()
        except:
            return defer.fail()

        try:
            # in this clause, we validate the outbound arguments against our
            # notion of what the other end will accept (the RemoteInterface)
            req = call.PendingRequest(reqID, self)

            # first, figure out which method they want to invoke

            (methodName, methodSchema) = self._getMethodInfo(_name)
            req.methodName = methodName # for debugging
            if methodConstraintOverride != "none":
                methodSchema = methodConstraintOverride
            if useSchema and methodSchema:
                # turn positional arguments into kwargs. mapArguments() could
                # fail for bad argument names or missing required parameters
                argsdict = methodSchema.mapArguments(args, kwargs)

                # check args against the arg constraint. This could fail if
                # any arguments are of the wrong type
                methodSchema.checkAllArgs(kwargs)

                # the Interface gets to constraint the return value too, so
                # make a note of it to use later
                req.setConstraint(methodSchema.getResponseConstraint())
            else:
                if args:
                    why = "positional arguments require a RemoteInterface"
                    why += " for %s.%s()" % (self, methodName)
                    raise tokens.BananaError(why)
                argsdict = kwargs

            # if the caller specified a _resultConstraint, that overrides
            # the schema's one
            if resultConstraint != "none":
                # overrides schema
                req.setConstraint(schema.makeConstraint(resultConstraint))

        except: # TODO: merge this with the next try/except clause
            # we have not yet sent anything to the far end. A failure here
            # is entirely local: stale broker, bad method name, bad
            # arguments. We abandon the PendingRequest, but errback the
            # Deferred it was going to use
            req.fail(failure.Failure())
            return req.deferred

        try:
            # once we start sending the CallSlicer, we could get either a
            # local or a remote failure, so we must be prepared to accept an
            # answer. After this point, we assign all responsibility to the
            # PendingRequest structure.
            self.tracker.broker.addRequest(req)

            # TODO: there is a decidability problem here: if the reqID made
            # it through, the other end will send us an answer (possibly an
            # error if the remaining slices were aborted). If not, we will
            # not get an answer. To decide whether we should remove our
            # broker.waitingForAnswers[] entry, we need to know how far the
            # slicing process made it.

            slicer = call.CallSlicer(reqID, self.tracker.clid,
                                     methodName, argsdict)

            # this could fail if any of the arguments (or their children)
            # are unsliceable
            d = broker.send(slicer)
            # d will fire when the last argument has been serialized. It
            # will errback if the arguments could not be serialized. We need
            # to catch this case and errback the caller.

        except:
            req.fail(failure.Failure())
            return req.deferred

        # if we got here, we have been able to start serializing the
        # arguments. If serialization fails, the PendingRequest needs to be
        # flunked (because we aren't guaranteed that the far end will do it).

        d.addErrback(req.fail)

        # the remote end could send back an error response for many reasons:
        #  bad method name
        #  bad argument types (violated their schema)
        #  exception during method execution
        #  method result violated the results schema
        # something else could occur to cause an errback:
        #  connection lost before response completely received
        #  exception during deserialization of the response
        #   [but only if it occurs after the reqID is received]
        #  method result violated our results schema
        # if none of those occurred, the callback will be run

        return req.deferred