Skip to content

Commit

Permalink
Move fixtures into a proper fixture
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalresistor committed May 23, 2017
1 parent e0f805e commit 77b47c9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 81 deletions.
68 changes: 68 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import pytest
import threading
import random
import logging
from contextlib import contextmanager

from wsgiref.simple_server import make_server
from wsgiref.simple_server import WSGIRequestHandler
from wsgiref.simple_server import WSGIServer
from wsgiref.simple_server import ServerHandler

log = logging.getLogger(__name__)
ServerHandler.handle_error = lambda: None


class QuietHandler(WSGIRequestHandler):
def log_request(self, *args):
pass

class QuietServer(WSGIServer):
def handle_error(self, req, addr):
pass

def _make_test_server(app):
maxport = ((1 << 16) - 1)

# we'll make 3 attempts to find a free port

for i in range(3, 0, -1):
try:
port = random.randint(maxport // 2, maxport)
server = make_server(
'localhost',
port,
app,
server_class=QuietServer,
handler_class=QuietHandler,
)
server.timeout = 5
return server
except:
if i == 1:
raise


@pytest.fixture
def serve():
@contextmanager
def _serve(app):
server = _make_test_server(app)
try:
worker = threading.Thread(target=server.serve_forever)
worker.setDaemon(True)
worker.start()
server.url = "http://localhost:%d" % server.server_port
log.debug("server started on %s", server.url)

yield server
finally:
log.debug("shutting server down")
server.shutdown()
worker.join(1)
if worker.isAlive():
log.warning('worker is hanged')
else:
log.debug("server stopped")

return _serve
14 changes: 8 additions & 6 deletions tests/test_client_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from webob import Request, Response
from webob.dec import wsgify
from webob.client import SendRequest
from .test_in_wsgiref import serve


@wsgify
Expand All @@ -16,8 +15,8 @@ def simple_app(req):
}
return Response(json=data)


def test_client(client_app=None):
@pytest.mark.usefixtures("serve")
def test_client(serve, client_app=None):
with serve(simple_app) as server:
req = Request.blank(server.url, method='POST', content_type='application/json',
json={'test': 1})
Expand Down Expand Up @@ -57,7 +56,8 @@ def no_length_app(environ, start_response):
return [b'ok']


def test_no_content_length(client_app=None):
@pytest.mark.usefixtures("serve")
def test_no_content_length(serve, client_app=None):
with serve(no_length_app) as server:
req = Request.blank(server.url)
resp = req.send(client_app)
Expand All @@ -73,7 +73,8 @@ def cookie_app(req):
return resp


def test_client_cookies(client_app=None):
@pytest.mark.usefixtures("serve")
def test_client_cookies(serve, client_app=None):
with serve(cookie_app) as server:
req = Request.blank(server.url + '/?test')
resp = req.send(client_app)
Expand All @@ -87,7 +88,8 @@ def slow_app(req):
return Response('ok')


def test_client_slow(client_app=None):
@pytest.mark.usefixtures("serve")
def test_client_slow(serve, client_app=None):
if client_app is None:
client_app = SendRequest()
if not client_app._timeout_supported(client_app.HTTPConnection):
Expand Down
87 changes: 12 additions & 75 deletions tests/test_in_wsgiref.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,29 @@
import sys
import logging
import threading
import random
import socket
import cgi

import pytest

from wsgiref.simple_server import make_server
from wsgiref.simple_server import WSGIRequestHandler
from wsgiref.simple_server import WSGIServer
from wsgiref.simple_server import ServerHandler

from webob.request import Request
from webob.response import Response
from webob.compat import url_open
from webob.compat import bytes_
from webob.compat import reraise
from webob.compat import Queue
from webob.compat import Empty
from contextlib import contextmanager

log = logging.getLogger(__name__)

def test_request_reading():
@pytest.mark.usefixtures("serve")
def test_request_reading(serve):
"""
Test actual request/response cycle in the presence of Request.copy()
and other methods that can potentially hang.
"""
with serve(_test_app_req_reading) as server:
for key in _test_ops_req_read:
resp = url_open(server.url+key, timeout=3)
resp = url_open(server.url + key, timeout=3)
assert resp.read() == b"ok"

def _test_app_req_reading(env, sr):
Expand All @@ -42,20 +35,16 @@ def _test_app_req_reading(env, sr):
r = Response("ok")
return r(env, sr)


_test_ops_req_read = {
'/copy': lambda req: req.copy(),
'/read-all': lambda req: req.body_file.read(),
'/read-0': lambda req: req.body_file.read(0),
'/make-seekable': lambda req: req.make_body_seekable()
}




# TODO: remove server logging for interrupted requests
# TODO: test interrupted body directly

def test_interrupted_request():
@pytest.mark.usefixtures("serve")
def test_interrupted_request(serve):
with serve(_test_app_req_interrupt) as server:
for path in _test_ops_req_interrupt:
_send_interrupted_req(server, path)
Expand All @@ -67,8 +56,10 @@ def test_interrupted_request():
print("Error during test:", path)
reraise(res)


_global_res = Queue()


def _test_app_req_interrupt(env, sr):
target_cl = 100000
try:
Expand All @@ -90,8 +81,7 @@ def _test_app_req_interrupt(env, sr):

def _req_int_cgi(req):
assert req.body_file.read(0) == b''
#req.environ.setdefault('CONTENT_LENGTH', '0')
d = cgi.FieldStorage(
cgi.FieldStorage(
fp=req.body_file,
environ=req.environ,
)
Expand All @@ -110,7 +100,7 @@ def _req_int_readline(req):
'/read-body': lambda req: req.body,
'/read-post': lambda req: req.POST,
'/read-all': lambda req: req.body_file.read(),
'/read-too-much': lambda req: req.body_file.read(1<<22),
'/read-too-much': lambda req: req.body_file.read(1 << 22),
'/readline': _req_int_readline,
'/readlines': lambda req: req.body_file.readlines(),
'/read-cgi': _req_int_cgi,
Expand All @@ -127,64 +117,11 @@ def _send_interrupted_req(server, path='/'):
f.close()
sock.close()


_interrupted_req = (
"POST %s HTTP/1.0\r\n"
"content-type: application/x-www-form-urlencoded\r\n"
"content-length: 100000\r\n"
"\r\n"
)
_interrupted_req += 'a=b\nz='+'x'*10000


@contextmanager
def serve(app):
server = _make_test_server(app)
try:
#worker = threading.Thread(target=server.handle_request)
worker = threading.Thread(target=server.serve_forever)
worker.setDaemon(True)
worker.start()
server.url = "http://localhost:%d" % server.server_port
log.debug("server started on %s", server.url)
yield server
finally:
log.debug("shutting server down")
server.shutdown()
worker.join(1)
if worker.isAlive():
log.warning('worker is hanged')
else:
log.debug("server stopped")


class QuietHanlder(WSGIRequestHandler):
def log_request(self, *args):
pass

ServerHandler.handle_error = lambda: None

class QuietServer(WSGIServer):
def handle_error(self, req, addr):
pass

def _make_test_server(app):
maxport = ((1<<16)-1)
# we'll make 3 attempts to find a free port
for i in range(3, 0, -1):
try:
port = random.randint(maxport//2, maxport)
server = make_server('localhost', port, app,
server_class=QuietServer,
handler_class=QuietHanlder
)
server.timeout = 5
return server
except:
if i == 1:
raise



if __name__ == '__main__':
#test_request_reading()
test_interrupted_request()
_interrupted_req += 'a=b\nz=' + 'x' * 10000

0 comments on commit 77b47c9

Please sign in to comment.