mirror of
https://github.com/jamesroberts/fastwsgi.git
synced 2025-12-30 10:49:46 -06:00
Testing overhaul
This commit is contained in:
4
clean_install.sh
Normal file
4
clean_install.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
sudo rm -rf /usr/local/lib/python3.8/dist-packages/_fastwsgi*;
|
||||
sudo rm -rf /usr/local/lib/python3.8/dist-packages/fastwsgi*;
|
||||
rm -rf build/ dist/ bin/ __pycache__/
|
||||
sudo python3 setup.py install
|
||||
@@ -48,9 +48,9 @@ def import_from_string(import_str):
|
||||
return module
|
||||
|
||||
|
||||
def print_server_details():
|
||||
def print_server_details(host, port):
|
||||
print(f"\n==== FastWSGI ==== ")
|
||||
print(f"Host: {HOST}\nPort: {PORT}")
|
||||
print(f"Host: {host}\nPort: {port}")
|
||||
print("==================\n")
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ def run_from_cli():
|
||||
_fastwsgi.run_server(wsgi_app, "", PORT, BACKLOG, LOGGING)
|
||||
|
||||
|
||||
def run(wsgi_app, host, port, backlog=1024):
|
||||
print_server_details()
|
||||
def run(wsgi_app, host=HOST, port=PORT, backlog=1024):
|
||||
print_server_details(host, port)
|
||||
print(f"Server listening at http://{host}:{port}")
|
||||
_fastwsgi.run_server(wsgi_app, host, port, backlog, LOGGING)
|
||||
# run_multi_process_server(wsgi_app)
|
||||
|
||||
5
lgtm.yml
5
lgtm.yml
@@ -1,4 +1,7 @@
|
||||
path_classifiers:
|
||||
library:
|
||||
- llhttp/**/*.c
|
||||
- llhttp/**/*.h
|
||||
- llhttp/**/*.h
|
||||
- libuv/**/*.c
|
||||
- libuv/**/*.h
|
||||
- performance_benchmarks/**/*.py
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
4
tests/apps_under_test/__init__.py
Normal file
4
tests/apps_under_test/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .basic_app import basic_app
|
||||
from .wsgi_app import wsgi_app
|
||||
from .flask_app import app as flask_app
|
||||
from .wsgi_validator_app import validator_app
|
||||
4
tests/apps_under_test/basic_app.py
Normal file
4
tests/apps_under_test/basic_app.py
Normal file
@@ -0,0 +1,4 @@
|
||||
def basic_app(environ, start_response):
|
||||
headers = [("Content-Type", "text/plain")]
|
||||
start_response("200 OK", headers)
|
||||
return [b"Hello World"]
|
||||
18
tests/apps_under_test/flask_app.py
Normal file
18
tests/apps_under_test/flask_app.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from flask import Flask
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.get("/get")
|
||||
def get():
|
||||
return "get", 200
|
||||
|
||||
|
||||
@app.post("/post")
|
||||
def post():
|
||||
return "post", 201
|
||||
|
||||
|
||||
@app.delete("/delete")
|
||||
def delete():
|
||||
return "delete", 204
|
||||
30
tests/apps_under_test/wsgi_app.py
Normal file
30
tests/apps_under_test/wsgi_app.py
Normal file
@@ -0,0 +1,30 @@
|
||||
def _get(environ, start_repsonse):
|
||||
assert environ.get("REQUEST_METHOD") == "GET"
|
||||
headers = [("Content-Type", "text/plain")]
|
||||
start_repsonse("200 OK", headers)
|
||||
return [b"OK"]
|
||||
|
||||
|
||||
def _post(environ, start_repsonse):
|
||||
assert environ.get("REQUEST_METHOD") == "POST"
|
||||
headers = [("Content-Type", "text/plain")]
|
||||
start_repsonse("201 Created", headers)
|
||||
return [b"OK"]
|
||||
|
||||
|
||||
def _delete(environ, start_response):
|
||||
assert environ.get("REQUEST_METHOD") == "DELETE"
|
||||
start_response("204 No Content", [])
|
||||
return [b""]
|
||||
|
||||
|
||||
routes = {
|
||||
"/get": _get,
|
||||
"/post": _post,
|
||||
"/delete": _delete,
|
||||
}
|
||||
|
||||
|
||||
def wsgi_app(environ, start_response):
|
||||
app = routes.get(environ["PATH_INFO"])
|
||||
return app(environ, start_response)
|
||||
11
tests/apps_under_test/wsgi_validator_app.py
Normal file
11
tests/apps_under_test/wsgi_validator_app.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from wsgiref.validate import validator
|
||||
|
||||
|
||||
def simple_app(environ, start_response):
|
||||
status = "200 OK"
|
||||
headers = [("Content-type", "text/plain")]
|
||||
start_response(status, headers)
|
||||
return [b"Valid"]
|
||||
|
||||
|
||||
validator_app = validator(simple_app)
|
||||
@@ -1,28 +1,96 @@
|
||||
import os
|
||||
import sys
|
||||
import pytest
|
||||
import fastwsgi
|
||||
import time
|
||||
from enum import Enum
|
||||
|
||||
from contextlib import contextmanager
|
||||
from multiprocessing import Process, set_start_method
|
||||
|
||||
from tests.apps_under_test import (
|
||||
basic_app,
|
||||
wsgi_app,
|
||||
flask_app,
|
||||
validator_app,
|
||||
)
|
||||
|
||||
HOST = "127.0.0.1"
|
||||
PORT = 8080
|
||||
PORT = 5000
|
||||
|
||||
|
||||
class ServerProcess:
|
||||
def __init__(self, application, host=HOST, port=PORT) -> None:
|
||||
self.process = Process(target=fastwsgi.run, args=(application, host, port))
|
||||
self.endpoint = f"http://{host}:{port}"
|
||||
self.host = host
|
||||
self.port = port
|
||||
|
||||
def __enter__(self):
|
||||
def start(self):
|
||||
self.process.start()
|
||||
time.sleep(1) # Allow server to start
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_tb):
|
||||
def kill(self):
|
||||
self.process.kill()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="session")
|
||||
def server_process():
|
||||
class Servers(Enum):
|
||||
BASIC_TEST_SERVER = 1
|
||||
WSGI_TEST_SERVER = 2
|
||||
FLASK_TEST_SERVER = 3
|
||||
VALIDATOR_TEST_SERVER = 4
|
||||
|
||||
|
||||
servers = {
|
||||
Servers.BASIC_TEST_SERVER: basic_app,
|
||||
Servers.WSGI_TEST_SERVER: wsgi_app,
|
||||
Servers.FLASK_TEST_SERVER: flask_app,
|
||||
Servers.VALIDATOR_TEST_SERVER: validator_app,
|
||||
}
|
||||
|
||||
|
||||
@contextmanager
|
||||
def mute_stdout():
|
||||
old_out = sys.stdout
|
||||
sys.stdout = open(os.devnull, "w")
|
||||
yield
|
||||
sys.stdout = old_out
|
||||
|
||||
|
||||
def pytest_sessionstart(session):
|
||||
set_start_method("fork")
|
||||
return ServerProcess
|
||||
for i, server in enumerate(servers.items()):
|
||||
with mute_stdout():
|
||||
name, app = server
|
||||
server_process = ServerProcess(app, port=PORT + i)
|
||||
server_process.start()
|
||||
print(f"{name} is listening on port={PORT+i}")
|
||||
servers[name] = server_process
|
||||
|
||||
|
||||
def pytest_sessionfinish(session, exitstatus):
|
||||
for server_process in servers.values():
|
||||
server_process.kill()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def server_process():
|
||||
return servers.get(Servers.BASIC_TEST_SERVER)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def basic_test_server():
|
||||
return servers.get(Servers.BASIC_TEST_SERVER)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def flask_test_server():
|
||||
return servers.get(Servers.FLASK_TEST_SERVER)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def wsgi_test_server():
|
||||
return servers.get(Servers.WSGI_TEST_SERVER)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def validator_test_server():
|
||||
return servers.get(Servers.VALIDATOR_TEST_SERVER)
|
||||
|
||||
@@ -1,40 +1,22 @@
|
||||
import requests
|
||||
from flask import Flask
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def get():
|
||||
return "get", 200
|
||||
def test_flask_get(flask_test_server):
|
||||
url = f"{flask_test_server.endpoint}/get"
|
||||
result = requests.get(url)
|
||||
assert result.status_code == 200
|
||||
assert result.text == "get"
|
||||
|
||||
|
||||
@app.post("/")
|
||||
def post():
|
||||
return "post", 201
|
||||
def test_flask_post(flask_test_server):
|
||||
url = f"{flask_test_server.endpoint}/post"
|
||||
result = requests.post(url, json={"test": "data"})
|
||||
assert result.status_code == 201
|
||||
assert result.text == "post"
|
||||
|
||||
|
||||
@app.delete("/")
|
||||
def delete():
|
||||
return "", 204
|
||||
|
||||
|
||||
def test_flask_get(server_process):
|
||||
with server_process(app) as server:
|
||||
result = requests.get(server.endpoint)
|
||||
assert result.status_code == 200
|
||||
assert result.text == "get"
|
||||
|
||||
|
||||
def test_flask_post(server_process):
|
||||
with server_process(app) as server:
|
||||
result = requests.post(server.endpoint, json={"test": "data"})
|
||||
assert result.status_code == 201
|
||||
assert result.text == "post"
|
||||
|
||||
|
||||
def test_flask_delete(server_process):
|
||||
with server_process(app) as server:
|
||||
result = requests.delete(server.endpoint)
|
||||
assert result.status_code == 204
|
||||
assert result.text == ""
|
||||
def test_flask_delete(flask_test_server):
|
||||
url = f"{flask_test_server.endpoint}/delete"
|
||||
result = requests.delete(url)
|
||||
assert result.status_code == 204
|
||||
assert result.text == ""
|
||||
|
||||
21
tests/test_raw_requests.py
Normal file
21
tests/test_raw_requests.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import socket
|
||||
import pytest
|
||||
|
||||
BAD_REQUEST_RESPONSE = b"HTTP/1.1 400 Bad Request\r\n\r\n"
|
||||
|
||||
raw_requests = [
|
||||
"GET\r\n\r\n",
|
||||
"/\r\n\r\n",
|
||||
"GET ???\r\n\r\n",
|
||||
"GET / HTTP\r\n\r\n",
|
||||
"\r\n",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("raw_request", raw_requests)
|
||||
def test_bad_requests(basic_test_server, raw_request):
|
||||
host, port = basic_test_server.host, basic_test_server.port
|
||||
connection = socket.create_connection((host, port))
|
||||
connection.send(raw_request.encode())
|
||||
data = connection.recv(4096)
|
||||
assert data == BAD_REQUEST_RESPONSE
|
||||
@@ -1,38 +0,0 @@
|
||||
import requests
|
||||
|
||||
|
||||
def wsgi_app(environ, start_response):
|
||||
start_response('200 OK', [('Content-Type', 'text/plain')])
|
||||
return [b"Hello, WSGI!"]
|
||||
|
||||
|
||||
def wsgi_app_delete(environ, start_response):
|
||||
start_response('204 No Content', [])
|
||||
return [b""]
|
||||
|
||||
|
||||
def test_uwsgi_get(server_process):
|
||||
with server_process(wsgi_app) as server:
|
||||
result = requests.get(server.endpoint)
|
||||
assert result.status_code == 200
|
||||
assert result.text == "Hello, WSGI!"
|
||||
|
||||
|
||||
def test_uwsgi_post(server_process):
|
||||
with server_process(wsgi_app) as server:
|
||||
# Post with no data
|
||||
result = requests.get(server.endpoint)
|
||||
assert result.status_code == 200
|
||||
assert result.text == "Hello, WSGI!"
|
||||
|
||||
# Post with data
|
||||
result = requests.get(server.endpoint, {"test": "data"})
|
||||
assert result.status_code == 200
|
||||
assert result.text == "Hello, WSGI!"
|
||||
|
||||
|
||||
def test_uwsgi_delete(server_process):
|
||||
with server_process(wsgi_app_delete) as server:
|
||||
result = requests.get(server.endpoint)
|
||||
assert result.status_code == 204
|
||||
assert result.text == ""
|
||||
@@ -1,25 +0,0 @@
|
||||
import requests
|
||||
|
||||
from wsgiref.validate import validator
|
||||
|
||||
|
||||
def simple_app(environ, start_response):
|
||||
status = '200 OK'
|
||||
headers = [('Content-type', 'text/plain')]
|
||||
start_response(status, headers)
|
||||
return [b"Valid"]
|
||||
|
||||
|
||||
validator_app = validator(simple_app)
|
||||
|
||||
|
||||
def test_get_valid_wsgi_server(server_process):
|
||||
with server_process(validator_app) as server:
|
||||
result = requests.get(server.endpoint)
|
||||
assert result.text == "Valid"
|
||||
|
||||
|
||||
def test_post_valid_wsgi_server(server_process):
|
||||
with server_process(validator_app) as server:
|
||||
result = requests.post(server.endpoint, json={"test": "data"})
|
||||
assert result.text == "Valid"
|
||||
29
tests/test_wsgi.py
Normal file
29
tests/test_wsgi.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import requests
|
||||
|
||||
|
||||
def test_wsgi_get(wsgi_test_server):
|
||||
url = f"{wsgi_test_server.endpoint}/get"
|
||||
result = requests.get(url)
|
||||
assert result.status_code == 200
|
||||
assert result.text == "OK"
|
||||
|
||||
|
||||
def test_wsgi_post(wsgi_test_server):
|
||||
# Post with no data
|
||||
url = f"{wsgi_test_server.endpoint}/post"
|
||||
|
||||
result = requests.post(url)
|
||||
assert result.status_code == 201
|
||||
assert result.text == "OK"
|
||||
|
||||
# Post with data
|
||||
result = requests.post(url, json={"test": "data"})
|
||||
assert result.status_code == 201
|
||||
assert result.text == "OK"
|
||||
|
||||
|
||||
def test_wsgi_delete(wsgi_test_server):
|
||||
url = f"{wsgi_test_server.endpoint}/delete"
|
||||
result = requests.delete(url)
|
||||
assert result.status_code == 204
|
||||
assert result.text == ""
|
||||
Reference in New Issue
Block a user