File: conftest.py

package info (click to toggle)
uranium 5.0.0-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,304 kB
  • sloc: python: 31,765; sh: 132; makefile: 12
file content (117 lines) | stat: -rw-r--r-- 4,212 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import threading

from twisted.internet import reactor
from twisted.web import resource, server, guard
from twisted.cred.portal import IRealm, Portal
from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse

from zope.interface import implementer


server_thread = None


# Start the local HTTP server before the tests start.
def pytest_configure(config):
    global server_thread
    server_thread = _runHttpServer()


# Stop the local HTTP server after the tests are done.
def pytest_unconfigure(config):
    global server_thread
    reactor.callLater(0, reactor.stop)
    server_thread.join()


#
# Run a local HTTP server for testing the HttpRequestManager.
# This server is accessible via http://localhost:8080/, and it has the following URL resources:
#  - /success  - This request will respond to a GET request normally with an HTML page.
#  - /timeout  - This request will respond to a GET request first with a few bytes and then do nothing.
#                It is intended to emulate a timeout.
#  - /auth     - Respond to GET requests and requires an authentication. You need to use Basic Auth with user:user as
#                the username and password to access this resource.
#
def _runHttpServer() -> "threading.Thread":
    class RootResource(resource.Resource):
        isLeaf = False

        def __init__(self):
            super().__init__()
            self._success = SuccessfulResource()
            self._timeout = TimeoutResource()

            checkers = [InMemoryUsernamePasswordDatabaseDontUse(user = b"user")]
            portal = Portal(SimpleRealm(), checkers)
            self._auth_resource = guard.HTTPAuthSessionWrapper(portal, [guard.BasicCredentialFactory("auth")])

        def getChild(self, name, request):
            if name == b"success":
                return self._success
            elif name == b"timeout":
                return self._timeout
            elif name == b"auth":
                return self._auth_resource
            return resource.Resource.getChild(self, name, request)

    # This resource can be accessed via /success. It will reply with an HTML page.
    class SuccessfulResource(resource.Resource):
        isLeaf = True

        def getChild(self, name, request):
            if name == b"":
                return self
            return resource.Resource.getChild(self, name, request)

        def render_GET(self, request):
            return "<html>Hello, world!</html>".encode("utf-8")

    # This resource can be accessed via /timeout. It will first send 3 replies, with 1 second between each. After that
    # It will not do anything to emulate a problem on the server side. This way we can test if the client side can
    # handle this case correctly, such as with a timeout.
    class TimeoutResource(resource.Resource):
        isLeaf = True

        def __init__(self):
            super().__init__()
            self._count = 0

        def getChild(self, name, request):
            if name == b"":
                return self
            return resource.Resource.getChild(self, name, request)

        def render_GET(self, request):
            self._process(request)
            return server.NOT_DONE_YET

        def _process(self, request):
            if self._count > 10:
                request.finish()

            if self._count == 3:
                # emulate a timeout by not replying anything
                return

            data = ("%s" % self._count) * 10
            request.write(data.encode("utf-8"))
            self._count += 1
            reactor.callLater(0.5, self._process, request)

    # A realm which gives out L{SuccessfulResource} instances for authenticated users.
    @implementer(IRealm)
    class SimpleRealm(object):
        def requestAvatar(self, avatar_id, mind, *interfaces):
            if resource.IResource in interfaces:
                return resource.IResource, SuccessfulResource(), lambda: None
            raise NotImplementedError()

    def _runServer():
        site = server.Site(RootResource())
        reactor.listenTCP(8080, site)
        reactor.run(installSignalHandlers= 0)

    t = threading.Thread(target = _runServer)
    t.start()
    return t