|
1 | 1 | from unittest import mock |
2 | 2 | from test import support |
3 | 3 | from test.support import socket_helper, control_characters_c0 |
| 4 | +from test.support.testcase import ExtraAssertions |
4 | 5 | from test.test_httpservers import NoLogRequestHandler |
5 | 6 | from unittest import TestCase |
6 | 7 | from wsgiref.util import setup_testing_defaults |
@@ -66,6 +67,26 @@ def header_app(environ, start_response): |
66 | 67 | ]).encode('iso-8859-1')] |
67 | 68 |
|
68 | 69 |
|
| 70 | +def input_app(func_name, *args): |
| 71 | + def app(e,s): |
| 72 | + req = getattr(e['wsgi.input'], func_name)(*args) |
| 73 | + s("200 OK", [("Content-Type", "text/plain; charset=utf-8")]) |
| 74 | + if type(req) is list: |
| 75 | + resp = b";".join(req) |
| 76 | + else: |
| 77 | + resp = req |
| 78 | + return [resp] |
| 79 | + return app |
| 80 | + |
| 81 | + |
| 82 | +def errors_app(func_name, *args): |
| 83 | + def app(e,s): |
| 84 | + getattr(e['wsgi.errors'], func_name)(*args) |
| 85 | + s("200 OK", [("Content-Type", "text/plain; charset=utf-8")]) |
| 86 | + return [b"data"] |
| 87 | + return app |
| 88 | + |
| 89 | + |
69 | 90 | def run_amock(app=hello_app, data=b"GET / HTTP/1.0\n\n"): |
70 | 91 | server = make_server("", 80, app, MockServer, MockHandler) |
71 | 92 | inp = BufferedReader(BytesIO(data)) |
@@ -102,7 +123,7 @@ def compare_generic_iter(make_it, match): |
102 | 123 | raise AssertionError("Too many items from .__next__()", it) |
103 | 124 |
|
104 | 125 |
|
105 | | -class IntegrationTests(TestCase): |
| 126 | +class IntegrationTests(TestCase, ExtraAssertions): |
106 | 127 |
|
107 | 128 | def check_hello(self, out, has_length=True): |
108 | 129 | pyver = (python_implementation() + "/" + |
@@ -192,6 +213,95 @@ def bad_app(e,s): |
192 | 213 | err.splitlines()[-2], "AssertionError" |
193 | 214 | ) |
194 | 215 |
|
| 216 | + def test_wsgi_input_read(self): |
| 217 | + bad_app = input_app("read") |
| 218 | + good_app = input_app("read", 5) |
| 219 | + |
| 220 | + out, err = run_amock(validator(bad_app)) |
| 221 | + self.assertEndsWith(out, |
| 222 | + b"A server error occurred. Please contact the administrator." |
| 223 | + ) |
| 224 | + |
| 225 | + self.assertEqual( |
| 226 | + err.splitlines()[-2], "AssertionError" |
| 227 | + ) |
| 228 | + |
| 229 | + out, err = run_amock(validator(good_app), b"GET / HTTP/1.0\n\nTest 1\nTest 2\n") |
| 230 | + self.assertEndsWith(out, b"Test ") |
| 231 | + |
| 232 | + def test_wsgi_input_readlines(self): |
| 233 | + bad_app = input_app("readlines", 3, 5) |
| 234 | + good_app = input_app("readlines", 1) |
| 235 | + |
| 236 | + out, err = run_amock(validator(bad_app)) |
| 237 | + self.assertEndsWith(out, |
| 238 | + b"A server error occurred. Please contact the administrator." |
| 239 | + ) |
| 240 | + self.assertEqual( |
| 241 | + err.splitlines()[-2], "AssertionError" |
| 242 | + ) |
| 243 | + out, err = run_amock(validator(good_app), b"GET / HTTP/1.0\n\nTest Line 1\nTest Line 2\n") |
| 244 | + self.assertEndsWith(out, b"Test Line 1\n") |
| 245 | + |
| 246 | + def test_wsgi_input_readline(self): |
| 247 | + bad_app = input_app("readline", 3, 4) |
| 248 | + good_app = input_app("readline", 2) |
| 249 | + |
| 250 | + out, err = run_amock(validator(bad_app)) |
| 251 | + self.assertEndsWith(out, |
| 252 | + b"A server error occurred. Please contact the administrator." |
| 253 | + ) |
| 254 | + self.assertEqual( |
| 255 | + err.splitlines()[-2], "AssertionError" |
| 256 | + ) |
| 257 | + |
| 258 | + out, err = run_amock(validator(good_app), b"GET / HTTP/1.0\n\nTest 1\nTest 2\n") |
| 259 | + self.assertEndsWith(out, b"Te") |
| 260 | + |
| 261 | + def test_wsgi_input_close(self): |
| 262 | + app = input_app("close") |
| 263 | + out, err = run_amock(validator(app), b"GET / HTTP/1.0\n\nTest 1\nTest 2\n") |
| 264 | + self.assertEqual(err.splitlines()[-2], 'AssertionError: input.close() must not be called') |
| 265 | + self.assertEndsWith(out, b"A server error occurred. Please contact the administrator.") |
| 266 | + |
| 267 | + def test_wsgi_input_iter(self): |
| 268 | + def app(e,s): |
| 269 | + req = [] |
| 270 | + for line in e['wsgi.input']: |
| 271 | + req.append(line) |
| 272 | + s("200 OK", [('Content-Type', 'text/plain; charser=utf-8')]) |
| 273 | + return [b';'.join(req)] |
| 274 | + |
| 275 | + out, err = run_amock(validator(app), b"GET / HTTP/1.0\n\nTest 1\nTest 2\n") |
| 276 | + self.assertEndsWith(out, b"Test 1\n;Test 2\n") |
| 277 | + |
| 278 | + def test_wsgi_errors_write(self): |
| 279 | + bad_app = errors_app("write", b"Test") |
| 280 | + good_app = errors_app("write", "Test") |
| 281 | + |
| 282 | + out, err = run_amock(validator(bad_app), b"GET / HTTP/1.0\n\n") |
| 283 | + self.assertEqual(err.splitlines()[-2], 'AssertionError') |
| 284 | + |
| 285 | + out, err = run_amock(validator(good_app), b"GET / HTTP/1.0\n\n") |
| 286 | + self.assertStartsWith(err, "Test") |
| 287 | + |
| 288 | + def test_wsgi_errors_writelines(self): |
| 289 | + bad_app = errors_app("writelines", [1, "Test"]) |
| 290 | + good_app = errors_app("writelines", ["Test", "Test"]) |
| 291 | + |
| 292 | + out, err = run_amock(validator(bad_app), b"GET / HTTP/1.0\n\n") |
| 293 | + self.assertEqual(err.splitlines()[-2], 'AssertionError') |
| 294 | + |
| 295 | + out, err = run_amock(validator(good_app), b"GET / HTTP/1.0\n\n") |
| 296 | + self.assertStartsWith(err, "TestTest") |
| 297 | + |
| 298 | + def test_wsgi_errors_close(self): |
| 299 | + app = errors_app("close") |
| 300 | + |
| 301 | + out, err = run_amock(validator(app), b"GET / HTTP/1.0\n\n") |
| 302 | + self.assertEqual(err.splitlines()[-2], |
| 303 | + 'AssertionError: errors.close() must not be called') |
| 304 | + |
195 | 305 | def test_bytes_validation(self): |
196 | 306 | def app(e, s): |
197 | 307 | s("200 OK", [ |
|
0 commit comments