예제 #1
0
    def test_doubleEncodingError(self):
        """
        If it is not possible to encode a response to the request (for example,
        because L{xmlrpclib.dumps} raises an exception when encoding a
        L{Fault}) the exception which prevents the response from being
        generated is logged and the request object is finished anyway.
        """
        logObserver = EventLoggingObserver()
        filtered = FilteringLogObserver(
            logObserver,
            [LogLevelFilterPredicate(defaultLogLevel=LogLevel.critical)])
        globalLogPublisher.addObserver(filtered)
        self.addCleanup(lambda: globalLogPublisher.removeObserver(filtered))
        d = self.proxy().callRemote("echo", "")

        # *Now* break xmlrpclib.dumps.  Hopefully the client already used it.
        def fakeDumps(*args, **kwargs):
            raise RuntimeError("Cannot encode anything at all!")

        self.patch(xmlrpclib, "dumps", fakeDumps)

        # It doesn't matter how it fails, so long as it does.  Also, it happens
        # to fail with an implementation detail exception right now, not
        # something suitable as part of a public interface.
        d = self.assertFailure(d, Exception)

        def cbFailed(ignored):
            # The fakeDumps exception should have been logged.
            self.assertEquals(1, len(logObserver))
            self.assertIsInstance(logObserver[0]["log_failure"].value,
                                  RuntimeError)
            self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)

        d.addCallback(cbFailed)
        return d
예제 #2
0
    def test_simpleFailureWithTraceback(self):
        """
        L{renderElement} will render a traceback when rendering of
        the element fails and our site is configured to display tracebacks.
        """
        logObserver = EventLoggingObserver.createWithCleanup(
            self,
            globalLogPublisher
        )
        self.request.site.displayTracebacks = True

        element = FailingElement()

        d = self.request.notifyFinish()

        def check(_):
            self.assertEquals(1, len(logObserver))
            f = logObserver[0]["log_failure"]
            self.assertIsInstance(f.value, FlattenerError)
            flushed = self.flushLoggedErrors(FlattenerError)
            self.assertEqual(len(flushed), 1)
            self.assertEqual(
                b"".join(self.request.written),
                b"<!DOCTYPE html>\n<p>I failed.</p>")
            self.assertTrue(self.request.finished)

        d.addCallback(check)

        renderElement(self.request, element, _failElement=TestFailureElement)

        return d
예제 #3
0
    def test_unexpectedLoginError(self):
        """
        Any unexpected failure from L{Portal.login} results in a 500 response
        code and causes the failure to be logged.
        """
        logObserver = EventLoggingObserver.createWithCleanup(
            self, globalLogPublisher)

        class UnexpectedException(Exception):
            pass

        class BrokenChecker:
            credentialInterfaces = (IUsernamePassword, )

            def requestAvatarId(self, credentials):
                raise UnexpectedException()

        self.portal.registerChecker(BrokenChecker())
        self.credentialFactories.append(BasicCredentialFactory('example.com'))
        request = self.makeRequest([self.childName])
        child = self._authorizedBasicLogin(request)
        request.render(child)
        self.assertEqual(request.responseCode, 500)
        self.assertEquals(1, len(logObserver))
        self.assertIsInstance(logObserver[0]["log_failure"].value,
                              UnexpectedException)
        self.assertEqual(len(self.flushLoggedErrors(UnexpectedException)), 1)
예제 #4
0
    def test_unexpectedDecodeError(self):
        """
        Any unexpected exception raised by the credential factory's C{decode}
        method results in a 500 response code and causes the exception to be
        logged.
        """
        logObserver = EventLoggingObserver.createWithCleanup(
            self, globalLogPublisher)

        class UnexpectedException(Exception):
            pass

        class BadFactory:
            scheme = b'bad'

            def getChallenge(self, client):
                return {}

            def decode(self, response, request):
                raise UnexpectedException()

        self.credentialFactories.append(BadFactory())
        request = self.makeRequest([self.childName])
        request.requestHeaders.addRawHeader(b'authorization', b'Bad abc')
        child = getChildForRequest(self.wrapper, request)
        request.render(child)
        self.assertEqual(request.responseCode, 500)
        self.assertEquals(1, len(logObserver))
        self.assertIsInstance(logObserver[0]["log_failure"].value,
                              UnexpectedException)
        self.assertEqual(len(self.flushLoggedErrors(UnexpectedException)), 1)
예제 #5
0
    def test_unknown_correlation_id(self):
        """
        A warning is logged and the connection dropped when a response with an
        unknown correlation ID is received.
        """
        events = EventLoggingObserver.createWithCleanup(self, globalLogPublisher)
        self.transport.bufferReceived(b'\0\0\0\x101234 more stuff..')
        self.assertTrue(self.transport.disconnecting)

        [event] = events
        self.assertEqual(LogLevel.warn, event['log_level'])
        self.assertEqual(self.peer, event['peer'])
        self.assertEqual(b'1234', event['correlation_id'])
예제 #6
0
    def test_unknown_correlation_id(self):
        """
        A warning is logged and the connection dropped when a response with an
        unknown correlation ID is received.
        """
        events = EventLoggingObserver.createWithCleanup(
            self, globalLogPublisher)
        self.transport.bufferReceived(b'\0\0\0\x101234 more stuff..')
        self.assertTrue(self.transport.disconnecting)

        [event] = events
        self.assertEqual(LogLevel.warn, event['log_level'])
        self.assertEqual(self.peer, event['peer'])
        self.assertEqual(b'1234', event['correlation_id'])
예제 #7
0
    def test_errors(self):
        """
        Verify that for each way a method exposed via XML-RPC can fail, the
        correct 'Content-type' header is set in the response and that the
        client-side Deferred is errbacked with an appropriate C{Fault}
        instance.
        """
        logObserver = EventLoggingObserver()
        filtered = FilteringLogObserver(
            logObserver,
            [LogLevelFilterPredicate(defaultLogLevel=LogLevel.critical)])
        globalLogPublisher.addObserver(filtered)
        self.addCleanup(lambda: globalLogPublisher.removeObserver(filtered))
        dl = []
        for code, methodName in [
            (666, "fail"),
            (666, "deferFail"),
            (12, "fault"),
            (23, "noSuchMethod"),
            (17, "deferFault"),
            (42, "SESSION_TEST"),
        ]:
            d = self.proxy().callRemote(methodName)
            d = self.assertFailure(d, xmlrpc.Fault)
            d.addCallback(
                lambda exc, code=code: self.assertEqual(exc.faultCode, code))
            dl.append(d)
        d = defer.DeferredList(dl, fireOnOneErrback=True)

        def cb(ign):
            for factory in self.factories:
                self.assertEqual(factory.headers[b"content-type"],
                                 b"text/xml; charset=utf-8")
            self.assertEquals(2, len(logObserver))
            f1 = logObserver[0]["log_failure"].value
            f2 = logObserver[1]["log_failure"].value

            if isinstance(f1, TestValueError):
                self.assertIsInstance(f2, TestRuntimeError)
            else:
                self.assertIsInstance(f1, TestRuntimeError)
                self.assertIsInstance(f2, TestValueError)

            self.flushLoggedErrors(TestRuntimeError, TestValueError)

        d.addCallback(cb)
        return d