Question

SSLTest.testError passes, but Trial raises an exception after tearDown. For comparison there is RegularTest.testOk that works OK. I have not found any Twisted bug that explain this, so I assume I'm doing something wrong given how easy this is to reproduce. Any ideas?

Here's the code:

from twisted.web import resource
from twisted.internet import ssl, reactor
from twisted.web.server import Site
from twisted.web.client import Agent, WebClientContextFactory
from twisted.trial.unittest import TestCase


class DummyServer(resource.Resource):
    isLeaf = True

    def render(self, request):
        return 'hello world'


class SSLTest(TestCase):
    def setUp(self):
        site = Site(DummyServer())
        SSLFactory = ssl.DefaultOpenSSLContextFactory('../server.key',
                                                      '../server.crt')
        port = reactor.listenSSL(0, site, contextFactory=SSLFactory)
        self.port = port
        self.portNumber = port._realPortNumber

    def tearDown(self):
        self.port.stopListening()

    def testError(self):
        def finished(result):
            self.assertEquals(result.code, 200)

        url = 'https://127.0.0.1:%s' % self.portNumber

        agent = Agent(reactor, WebClientContextFactory())
        d = agent.request('GET', url)
        d.addCallback(finished)
        return d


class RegularTest(TestCase):
    def setUp(self):
        site = Site(DummyServer())
        port = reactor.listenTCP(0, site)
        self.port = port
        self.portNumber = port._realPortNumber

    def tearDown(self):
        self.port.stopListening()

    def testOk(self):
        def finished(result):
            self.assertEquals(result.code, 200)

        url = 'http://127.0.0.1:%s' % self.portNumber

        agent = Agent(reactor,)
        d = agent.request('GET', url)
        d.addCallback(finished)
        return d

Here's stdout:

$ trial trialerror.py
trialerror
  RegularTest
    testOk ...                                                             [OK]
  SSLTest
    testError ...                                                          [OK]
                                                      [ERROR]

===============================================================================
[ERROR]
Traceback (most recent call last):
Failure: twisted.trial.util.DirtyReactorAggregateError: Reactor was unclean.
Selectables:
<TLSMemoryBIOProtocol #0 on 51135>

trialerror.SSLTest.testError
-------------------------------------------------------------------------------
Ran 2 tests in 0.018s

FAILED (errors=1, successes=2)
Was it helpful?

Solution

Jonathan Lange wrote about this problem and its solutions. You may also want to consider not using real network connections in your unit tests. Agent already works. So do Site, reactor.listenSSL, etc. Try to write unit tests that exercise your code and not lots and lots of code from the libraries your code depends on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top