~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/web2/test/test_wsgi.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mto: (2.2.3 sid)
  • mto: This revision was merged to the branch mainline in revision 15.
  • Revision ID: james.westby@ubuntu.com-20070117145235-7gaj253qxi5wiq16
Tags: upstream-2.5.0
ImportĀ upstreamĀ versionĀ 2.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from __future__ import generators
 
2
 
 
3
import time
 
4
from twisted.web2.test.test_server import BaseCase
 
5
from twisted.web2 import resource
 
6
from twisted.internet import reactor, interfaces
 
7
from twisted.python import log
 
8
 
 
9
if interfaces.IReactorThreads(reactor, None) is not None:
 
10
    from twisted.web2.wsgi import WSGIResource as WSGI
 
11
else:
 
12
    WSGI = None
 
13
 
 
14
class TestError(Exception):
 
15
    pass
 
16
 
 
17
class TestContainer(BaseCase):
 
18
    wait_timeout = 10.0
 
19
 
 
20
    def flushErrors(self, result, error):
 
21
        log.flushErrors(error)
 
22
        return result
 
23
    
 
24
    def test_getContainedResource(self):
 
25
        """Test that non-blocking WSGI applications render properly."""
 
26
        def application(environ, start_response):
 
27
            status = '200 OK'
 
28
            response_headers = [('Content-type','text/html')]
 
29
            writer = start_response(status, response_headers)
 
30
            writer('<html>')
 
31
            return ['<h1>Some HTML</h1>',
 
32
                    '</html>']
 
33
 
 
34
        return self.assertResponse(
 
35
            (WSGI(application), 'http://host/'),
 
36
            (200, {"Content-Length": None}, '<html><h1>Some HTML</h1></html>'))
 
37
 
 
38
    def test_getBlockingResource(self):
 
39
        """Test that blocking WSGI applications render properly."""
 
40
        def application(environ, start_response):
 
41
            """Simplest possible application object"""
 
42
            status = '200 OK'
 
43
            response_headers = [('Content-type','text/html')]
 
44
            writer = start_response(status, response_headers)
 
45
            writer('<h1>A little bit')
 
46
            time.sleep(1)
 
47
            writer(' of HTML</h1>')
 
48
            time.sleep(1)
 
49
            return ['<p>Hello!</p>']
 
50
 
 
51
        return self.assertResponse(
 
52
            (WSGI(application), 'http://host/'),
 
53
            (200, {"Content-Length": None}, '<h1>A little bit of HTML</h1><p>Hello!</p>'))
 
54
 
 
55
    def test_responseCode(self):
 
56
        """Test that WSGIResource handles strange response codes properly."""
 
57
        def application(environ, start_response):
 
58
            status = '314'
 
59
            response_headers = [('Content-type','text/html')]
 
60
            writer = start_response(status, response_headers)
 
61
            return []
 
62
 
 
63
        return self.assertResponse(
 
64
            (WSGI(application), 'http://host/'),
 
65
            (314, {"Content-Length": 0}, ''))
 
66
 
 
67
    def test_errorfulResource(self):
 
68
        def application(environ, start_response):
 
69
            raise TestError("This is an expected error")
 
70
        
 
71
        return self.assertResponse(
 
72
            (WSGI(application), 'http://host/'),
 
73
            (500, {}, None)).addBoth(self.flushErrors, TestError)
 
74
 
 
75
    def test_errorfulResource2(self):
 
76
        def application(environ, start_response):
 
77
            write = start_response("200 OK", {})
 
78
            write("Foo")
 
79
            raise TestError("This is an expected error")
 
80
        
 
81
        return self.assertResponse(
 
82
            (WSGI(application), 'http://host/'),
 
83
            (200, {"Content-Length": None}, "Foo"), failure=True
 
84
            ).addBoth(self.flushErrors, TestError)
 
85
    
 
86
    def test_errorfulIterator(self):
 
87
        def iterator():
 
88
            raise TestError("This is an expected error")
 
89
        
 
90
        def application(environ, start_response):
 
91
            start_response("200 OK", {})
 
92
            return iterator()
 
93
        
 
94
        return self.assertResponse(
 
95
            (WSGI(application), 'http://host/'),
 
96
            (500, {}, None)).addBoth(self.flushErrors, TestError)
 
97
 
 
98
    def test_errorfulIterator2(self):
 
99
        def iterator():
 
100
            yield "Foo"
 
101
            yield "Bar"
 
102
            raise TestError("This is also expected")
 
103
        
 
104
        def application(environ, start_response):
 
105
            start_response("200 OK", {})
 
106
            return iterator()
 
107
        
 
108
        return self.assertResponse(
 
109
            (WSGI(application), 'http://host/'),
 
110
            (200, {"Content-Length": None}, "FooBar"), failure=True
 
111
            ).addBoth(self.flushErrors, TestError)
 
112
 
 
113
    def test_didntCallStartResponse(self):
 
114
        def application(environ, start_response):
 
115
            return ["Foo"]
 
116
        
 
117
        return self.assertResponse(
 
118
            (WSGI(application), 'http://host/'),
 
119
            (500, {}, None)).addBoth(self.flushErrors, RuntimeError)
 
120
 
 
121
    def test_calledStartResponseLate(self):
 
122
        def application(environ, start_response):
 
123
            start_response("200 OK", {})
 
124
            yield "Foo"
 
125
        
 
126
        return self.assertResponse(
 
127
            (WSGI(application), 'http://host/'),
 
128
            (200, {"Content-Length": None}, "Foo"))
 
129
 
 
130
    def test_returnList(self):
 
131
        def application(environ, start_response):
 
132
            write = start_response("200 OK", {})
 
133
            return ["Foo", "Bar"]
 
134
        
 
135
        return self.assertResponse(
 
136
            (WSGI(application), 'http://host/'),
 
137
            (200, {"Content-Length": 6}, "FooBar"))
 
138
 
 
139
    def test_readAllInput(self):
 
140
        def application(environ, start_response):
 
141
            input = environ['wsgi.input']
 
142
            out = input.read(-1)
 
143
            start_response("200 OK", {})
 
144
            return [out]
 
145
        
 
146
        return self.assertResponse(
 
147
            (WSGI(application), 'http://host/', {}, None, None, '', "This is some content"),
 
148
            (200, {"Content-Length": 20}, "This is some content"))
 
149
 
 
150
    def test_readInputLines(self):
 
151
        def application(environ, start_response):
 
152
            input = environ['wsgi.input']
 
153
            out = 'X'.join(input.readlines())
 
154
            start_response("200 OK", {})
 
155
            return [out]
 
156
        
 
157
        d = self.assertResponse(
 
158
            (WSGI(application), 'http://host/', {}, None, None, '', "a\nb\nc"),
 
159
            (200, {"Content-Length": 7}, "a\nXb\nXc"))
 
160
 
 
161
        d.addCallback(lambda d: self.assertResponse(
 
162
            (WSGI(application), 'http://host/', {}, None, None, '', "a\nb\n"),
 
163
            (200, {"Content-Length": 5}, "a\nXb\n")))
 
164
        return d
 
165
 
 
166
    def test_readInputLineSizeNegZero(self):
 
167
        """Test that calling wsgi.input.readline works with -1 and 0 and none."""
 
168
        def application(environ, start_response):
 
169
            input = environ['wsgi.input']
 
170
 
 
171
            out = [input.read(5)] # 'Line '
 
172
            out.extend(["X", input.readline(-1)]) # 'blah blah\n'
 
173
            out.extend(["X", input.readline(0)])  # ''
 
174
            out.extend(["X", input.readline(None)]) # 'Oh Line\n'
 
175
            out.extend(["X", input.readline()])   # ''
 
176
 
 
177
            start_response("200 OK", {})
 
178
            return out
 
179
 
 
180
        return self.assertResponse(
 
181
            (WSGI(application), 'http://host/', {}, None, None, '',
 
182
             "Line blah blah\nOh Line\n"),
 
183
            (200, {"Content-Length": 27},
 
184
             "Line Xblah blah\nXXOh Line\nX"))
 
185
 
 
186
    def test_readInputLineSize(self):
 
187
        """Test that readline() with a size works."""
 
188
        def application(environ, start_response):
 
189
            input = environ['wsgi.input']
 
190
 
 
191
            out = [input.read(5)]           # 'Line '
 
192
            out.extend(["X", input.readline(5)]) # 'blah '
 
193
            out.extend(["X", input.readline()])  # 'blah\n'
 
194
            out.extend(["X", input.readline(1)])     # 'O'
 
195
            out.extend(["X", input.readline()])  # 'h Line\n'
 
196
 
 
197
            start_response("200 OK", {})
 
198
            return out
 
199
 
 
200
        return self.assertResponse(
 
201
            (WSGI(application), 'http://host/', {}, None, None, '',
 
202
             "Line blah blah\nOh Line\n"),
 
203
            (200, {"Content-Length": 27},
 
204
             "Line Xblah Xblah\nXOXh Line\n"))
 
205
 
 
206
    def test_readInputMixed(self):
 
207
        def application(environ, start_response):
 
208
            input = environ['wsgi.input']
 
209
            out = [input.read(5)]
 
210
            out.extend(["X", input.readline()])
 
211
            out.extend(["X", input.read(1)])
 
212
            out.extend(["X", input.readline()])
 
213
            
 
214
            start_response("200 OK", {})
 
215
            return out
 
216
        
 
217
        return self.assertResponse(
 
218
            (WSGI(application), 'http://host/', {}, None, None, '',
 
219
             "Line blah blah\nOh Line\n"),
 
220
            (200, {"Content-Length": 26}, "Line Xblah blah\nXOXh Line\n"))
 
221
 
 
222
    def test_readiter(self):
 
223
        """Test that using wsgi.input as an iterator works."""
 
224
        def application(environ, start_response):
 
225
            input = environ['wsgi.input']
 
226
            out = 'X'.join(input)
 
227
            
 
228
            start_response("200 OK", {})
 
229
            return [out]
 
230
        
 
231
        return self.assertResponse(
 
232
            (WSGI(application), 'http://host/', {}, None, None, '',
 
233
             "Line blah blah\nOh Line\n"),
 
234
            (200, {"Content-Length": 24}, "Line blah blah\nXOh Line\n"))
 
235
        
 
236
class TestWSGIEnvironment(BaseCase):
 
237
    """
 
238
    Test that the WSGI container does everything we expect it to do
 
239
    with the WSGI environment dictionary.
 
240
    """
 
241
    def envApp(self, *varnames):
 
242
        """
 
243
        Return a WSGI application that writes environment variables.
 
244
        """
 
245
        def _app(environ, start_response):
 
246
            status = '200'
 
247
            response_headers = [('Content-type','text/html')]
 
248
            writer = start_response(status, response_headers)
 
249
            return ['%s=%r;' % (k, environ.get(k, '')) for k in varnames]
 
250
        return _app
 
251
 
 
252
    def assertEnv(self, uri, env, version=None):
 
253
        keys = env.keys()
 
254
        keys.sort()
 
255
        envstring = ''.join(['%s=%r;' % (k, v) for k, v in env.items()])
 
256
        self.assertResponse(
 
257
            (WSGI(self.envApp(*keys)), uri, None, None, version),
 
258
            (200, {}, envstring))
 
259
 
 
260
    def test_wsgi_url_scheme(self):
 
261
        """wsgi.url_scheme"""
 
262
        self.assertEnv('https://host/', {'wsgi.url_scheme': 'https'})
 
263
        self.assertEnv('http://host/', {'wsgi.url_scheme': 'http'})
 
264
 
 
265
    def test_SERVER_PROTOCOL(self):
 
266
        """SERVER_PROTOCOL"""
 
267
        self.assertEnv('http://host/', {'SERVER_PROTOCOL': 'HTTP/1.1'})
 
268
 
 
269
    def test_SERVER_PORT(self):
 
270
        """SERVER_PORT"""
 
271
        self.assertEnv('http://host/', {'SERVER_PORT': '80'})
 
272
        self.assertEnv('http://host:523/', {'SERVER_PORT': '523'})
 
273
        self.assertEnv('https://host/', {'SERVER_PORT': '443'})
 
274
        self.assertEnv('https://host:523/', {'SERVER_PORT': '523'})
 
275
        self.assertEnv('/foo', {'SERVER_PORT': '80'}, version=(1,0))
 
276
 
 
277
if WSGI is None:
 
278
    for cls in (TestContainer, TestWSGIEnvironment):
 
279
        setattr(cls, 'skip', 'Required thread support is missing, skipping')