Provide reusable code to create a safe twisted tcp server for tests

Bug #944125 reported by Manuel de la Peña
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
ubuntuone-dev-tools
Status tracked in Trunk
Trunk
Fix Committed
Low
Manuel de la Peña

Bug Description

During the development of the proxy code we have been writing several times the same server code to fake a connection. The common code looks like the following:

SAMPLE_CONTENT = "hello world!"
SIMPLERESOURCE = "simpleresource"
DUMMY_KEY_FILENAME = "dummy.key"
DUMMY_CERT_FILENAME = "dummy.cert"

class SaveHTTPChannel(http.HTTPChannel):
    """A save protocol to be used in tests."""

    protocolInstance = None

    # pylint: disable=C0103
    def connectionMade(self):
        """Keep track of the given protocol."""
        SaveHTTPChannel.protocolInstance = self
        http.HTTPChannel.connectionMade(self)

class SaveSite(server.Site):
    """A site that let us know when it's closed."""

    protocol = SaveHTTPChannel

    def __init__(self, *args, **kwargs):
        """Create a new instance."""
        server.Site.__init__(self, *args, **kwargs)
        # we disable the timeout in the tests, we will deal with it manually.
        # pylint: disable=C0103
        self.timeOut = None

class BaseMockWebServer(object):
    """A mock webserver for testing"""

    def __init__(self):
        """Start up this instance."""
        self.root = self.get_root_resource()
        self.site = SaveSite(self.root)
        application = service.Application('web')
        self.service_collection = service.IServiceCollection(application)
        #pylint: disable=E1101
        self.tcpserver = internet.TCPServer(0, self.site)
        self.tcpserver.setServiceParent(self.service_collection)
        self.sslserver = internet.SSLServer(0, self.site, self.get_context())
        self.sslserver.setServiceParent(self.service_collection)
        self.service_collection.startService()

    def get_dummy_path(self, filename):
        """Path pointing at the dummy certificate files."""
        base_path = path.dirname(__file__)
        return path.join(base_path, "ssl", filename)

    def get_context(self):
        """Return an ssl context."""
        key_path = self.get_dummy_path(DUMMY_KEY_FILENAME)
        cert_path = self.get_dummy_path(DUMMY_CERT_FILENAME)
        return ssl.DefaultOpenSSLContextFactory(key_path, cert_path)

    def get_root_resource(self):
        """Get the root resource with all the children."""
        raise NotImplementedError

    def get_iri(self):
        """Build the iri for this mock server."""
        #pylint: disable=W0212
        port_num = self.tcpserver._port.getHost().port
        return u"http://0.0.0.0:%d/" % port_num

    def get_ssl_iri(self):
        """Build the iri for the ssl mock server."""
        #pylint: disable=W0212
        port_num = self.sslserver._port.getHost().port
        return u"https://0.0.0.0:%d/" % port_num

   def stop(self):
        """Shut it down."""
        #pylint: disable=E1101
        if self.site.protocol.protocolInstance:
            self.site.protocol.protocolInstance.timeoutConnection()
        return self.service_collection.stopService()

class SimpleResource(resource.Resource):
    """A simple web resource."""

    def __init__(self):
        """Initialize this mock resource."""
        resource.Resource.__init__(self)
        self.rendered = defer.Deferred()

    def render_GET(self, request):
        """Make a bit of html out of the resource's content."""
        if not self.rendered.called:
            self.rendered.callback(None)
        return SAMPLE_CONTENT

class MockWebServer(BaseMockWebServer):
    """A mock webserver."""

    def __init__(self):
        """Initialize this mock server."""
        self.simple_resource = SimpleResource()
        super(MockWebServer, self).__init__()

    def get_root_resource(self):
        """Get the root resource with all the children."""
        root = resource.Resource()
        root.putChild(SIMPLERESOURCE, self.simple_resource)
        return root

It makes sense that we move the code to this more common project.

Tags: u1-proxy
Changed in ubuntuone-dev-tools:
assignee: nobody → Ubuntu One Desktop+ team (ubuntuone-desktop+)
importance: Undecided → Low
status: New → Triaged
dobey (dobey)
summary: - Provide reusable code to create a twisted save server for tests
+ Provide reusable code to create a safe twisted tcp server for tests
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.