mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-01 18:21:30 +08:00
Add comprehensive integration tests verifying gunicorn's uWSGI binary protocol works correctly with nginx's uwsgi_pass directive. Test categories: - Basic GET/POST requests with query strings and large bodies - Header preservation (custom headers, Host, Content-Type) - HTTP keep-alive connections - Error responses (400-503 status codes) - WSGI environ variables - Large response streaming (1MB) - Concurrent request handling - Edge cases (binary data, unicode, long headers) Architecture: pytest -> nginx:8080 -> uwsgi_pass -> gunicorn:8000 Also adds GitHub Actions workflow that runs on changes to uwsgi module or docker test files.
3.7 KiB
3.7 KiB
uWSGI Protocol Docker Integration Tests
This directory contains Docker-based integration tests that verify gunicorn's
uWSGI binary protocol implementation works correctly with nginx's uwsgi_pass
directive.
Architecture
[pytest] --HTTP--> [nginx:8080] --uwsgi_pass--> [gunicorn:8000]
The tests make HTTP requests to nginx, which proxies them to gunicorn using the uWSGI binary protocol. This validates the complete request/response cycle through the protocol.
Prerequisites
- Docker
- Docker Compose (v2)
- Python 3.8+
- pytest
- requests
Running Tests
From repository root:
# Run all uWSGI integration tests
pytest tests/docker/uwsgi/ -v
# Run specific test class
pytest tests/docker/uwsgi/ -v -k TestBasicRequests
# Skip Docker tests (for CI environments without Docker)
pytest tests/ -v -m "not docker"
Manual testing:
cd tests/docker/uwsgi
# Start services
docker compose up -d
# Wait for services to be healthy
docker compose ps
# Test endpoints
curl http://localhost:8080/
curl -X POST -d "test body" http://localhost:8080/echo
curl http://localhost:8080/headers
curl "http://localhost:8080/query?foo=bar"
curl http://localhost:8080/environ
curl http://localhost:8080/error/404
curl http://localhost:8080/large > /dev/null # 1MB response
# View logs
docker compose logs gunicorn
docker compose logs nginx
# Stop services
docker compose down -v
Test Categories
| Category | Description |
|---|---|
TestBasicRequests |
GET, POST, query strings, large bodies |
TestHeaderPreservation |
Custom headers, Host, Content-Type, User-Agent |
TestKeepAlive |
Multiple requests per connection |
TestErrorResponses |
HTTP error codes (400, 404, 500, etc.) |
TestEnvironVariables |
WSGI environ: REQUEST_METHOD, PATH_INFO, etc. |
TestLargeResponses |
1MB response body streaming |
TestConcurrency |
Parallel request handling |
TestSpecialCases |
Edge cases: binary data, unicode, long headers |
Files
| File | Purpose |
|---|---|
docker-compose.yml |
Orchestrates nginx + gunicorn containers |
Dockerfile.gunicorn |
Builds gunicorn image with test app |
Dockerfile.nginx |
Builds nginx with uwsgi config |
nginx.conf |
nginx configuration using uwsgi_pass |
uwsgi_params |
Standard uwsgi parameter mappings |
app.py |
Test WSGI application with multiple endpoints |
conftest.py |
pytest fixtures for Docker lifecycle |
test_uwsgi_integration.py |
Test cases |
Test App Endpoints
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Basic hello response |
/echo |
POST | Echo request body |
/headers |
GET/POST | Return received headers as JSON |
/environ |
GET/POST | Return WSGI environ as JSON |
/query |
GET | Return query params as JSON |
/json |
POST | Parse and echo JSON body |
/error/{code} |
GET | Return specified HTTP error |
/large |
GET | Return 1MB response |
Gunicorn Configuration
The gunicorn container runs with:
gunicorn \
--protocol uwsgi \
--uwsgi-allow-from "*" \
--bind 0.0.0.0:8000 \
--workers 2 \
--log-level debug \
app:application
Key settings:
--protocol uwsgi: Enable uWSGI binary protocol--uwsgi-allow-from "*": Accept connections from Docker network IPs
Troubleshooting
Services won't start
Check Docker logs:
docker compose logs
Connection refused
Wait for health checks:
docker compose ps # Check health status
Tests timing out
Increase STARTUP_TIMEOUT in conftest.py or check if ports are in use:
lsof -i :8080
lsof -i :8000
Rebuild after code changes
docker compose build --no-cache
docker compose up -d