Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
201 lines (167 loc) · 6.89 KB
/
Copy pathMakefile
File metadata and controls
201 lines (167 loc) · 6.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# Makefile frontend for scikit-build-core project
#
# This Makefile wraps common build commands for convenience.
# The actual build is handled by scikit-build-core via pyproject.toml
.PHONY: all sync build rebuild test lint format typecheck qa clean \
distclean wheel sdist dist check publish-test publish upgrade \
coverage coverage-html docs docs-serve docs-deploy release \
build-asan test-asan test-leaks \
bench bench-quick bench-load bench-compare bench-server help
# Default target
all: build
# Sync environment (initial setup, installs dependencies + package)
sync:
@uv sync
# Build/rebuild the extension after code changes
build:
@uv sync --reinstall-package cymongoose
# Alias for build
rebuild: build
# Run tests
test:
@uv run python -m pytest tests/ -v
# Lint with ruff
lint:
@uv run ruff check --fix src/ tests/
# Format with ruff
format:
@uv run ruff format src/ tests/
# Type check with mypy
typecheck:
@uv run mypy --strict src --exclude '.venv'
# Run lint, type check, and format (run `make test` separately)
qa: lint typecheck format
# Build wheel
wheel:
@uv build --wheel
# Build source distribution
sdist:
@uv build --sdist
# Check distributions with twine
check:
@uv run twine check dist/*
# Build both wheel and sdist
dist: wheel sdist check
# Publish to TestPyPI
publish-test: check
@uv run twine upload --repository testpypi dist/*
# Publish to PyPI
publish: check
@uv run twine upload dist/*
# Upgrade all dependencies
upgrade:
@uv lock --upgrade
@uv sync
# Run tests with coverage
coverage:
@uv run python -m pytest tests/ -v --cov=src/cymongoose --cov-report=term-missing
# Generate HTML coverage report
coverage-html:
@uv run python -m pytest tests/ -v --cov=src/cymongoose --cov-report=html
@echo "Coverage report: htmlcov/index.html"
# Build documentation (requires mkdocs + mkdocs-material in dev dependencies)
docs:
@uv run mkdocs build
# Serve documentation locally with live reload
docs-serve:
@uv run mkdocs serve
# Deploy documentation to GitHub Pages
docs-deploy:
@uv run mkdocs gh-deploy --force
# Build with AddressSanitizer enabled
# Also compiles a small helper (build/run_asan) that injects the ASAN runtime
# via DYLD_INSERT_LIBRARIES before exec'ing Python. This is needed on macOS
# because SIP strips DYLD_INSERT_LIBRARIES from processes spawned by
# SIP-protected binaries (/usr/bin/make, /bin/sh, /bin/zsh, etc.).
ASAN_LIB := $(shell find /Applications/Xcode.app -name "libclang_rt.asan_osx_dynamic.dylib" 2>/dev/null | head -1)
build-asan: clean
SKBUILD_CMAKE_DEFINE="USE_ASAN=ON" uv sync --reinstall-package cymongoose
@mkdir -p build
@printf '#include <stdlib.h>\n#include <unistd.h>\nint main(int c,char**v){setenv("DYLD_INSERT_LIBRARIES",v[1],1);execvp(v[2],v+2);return 1;}\n' \
| cc -o build/run_asan -x c -
@echo "ASAN helper built: build/run_asan"
# Run tests with AddressSanitizer
test-asan: build-asan
@echo "Running tests with AddressSanitizer..."
ASAN_OPTIONS=detect_leaks=0:allocator_may_return_null=1:halt_on_error=1 \
build/run_asan $(ASAN_LIB) .venv/bin/python -m pytest tests/ -v -x --tb=short
@echo "ASAN tests completed successfully"
# Run tests under macOS `leaks` tool to detect memory leaks
# Requires macOS with developer tools installed.
# The `leaks` tool attaches to the process and reports any leaked allocations
# after the test suite completes. Exit code is non-zero if leaks are found.
test-leaks:
@echo "Running tests with macOS leaks tool..."
MallocStackLogging=1 leaks --atExit -- .venv/bin/python -m pytest tests/ -x --tb=short -q 2>&1 \
| grep -E '(passed|failed|error|Process [0-9]|LEAK|ROOT LEAK|leaked bytes)'
@echo "Leak check completed"
# ---------------------------------------------------------------------------
# Benchmarks
# ---------------------------------------------------------------------------
# Start the demo server for manual benchmarking with wrk or ab
bench-server:
@echo "Starting cymongoose demo server on http://localhost:8765 ..."
@echo "Run: wrk -t4 -c100 -d10s http://localhost:8765/"
@uv run python tests/benchmarks/demo_server.py
# Quick sequential benchmark (1000 requests, no external tools needed)
bench-quick:
@uv run python tests/benchmarks/quick_bench.py
# Concurrent load test (5000 requests, 50 concurrent)
bench-load:
@uv run python tests/benchmarks/simple_load_test.py
# Automated framework comparison using Apache Bench (requires ab)
bench-compare:
@uv run python tests/benchmarks/run_benchmark.py
# Run quick + load benchmarks
bench: bench-quick bench-load
# Clean build artifacts
clean:
@rm -rf build/
@rm -rf dist/
@rm -rf *.egg-info/
@rm -rf src/*.egg-info/
@rm -rf .pytest_cache/
@# Prune .venv: it holds every installed package's compiled extensions, and
@# `build-asan: clean` would otherwise strip them (mypy's librt, for one).
@# rm -f rather than -delete, which implies -depth and so voids -prune.
@find . -path ./.venv -prune -o -name "*.so" -exec rm -f {} +
@find . -path ./.venv -prune -o -name "*.pyd" -exec rm -f {} +
@find . -path ./.venv -prune -o -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
# Clean everything including CMake cache
distclean: clean
@rm -rf CMakeCache.txt CMakeFiles/
# Show help
help:
@echo "Available targets:"
@echo " all - Build/rebuild the extension (default)"
@echo " sync - Sync environment (initial setup)"
@echo " build - Rebuild extension after code changes"
@echo " rebuild - Alias for build"
@echo " test - Run tests"
@echo " lint - Lint with ruff"
@echo " format - Format with ruff"
@echo " typecheck - Type check with mypy"
@echo " qa - Run lint, typecheck, and format"
@echo " wheel - Build wheel distribution"
@echo " sdist - Build source distribution"
@echo " dist - Build both wheel and sdist"
@echo " check - Check distributions with twine"
@echo " publish-test - Publish to TestPyPI"
@echo " publish - Publish to PyPI"
@echo " upgrade - Upgrade all dependencies"
@echo " coverage - Run tests with coverage"
@echo " coverage-html- Generate HTML coverage report"
@echo " docs - Build documentation with MkDocs"
@echo " docs-serve - Serve documentation locally with live reload"
@echo " docs-deploy - Deploy documentation to GitHub Pages"
@echo " build-asan - Build with AddressSanitizer"
@echo " test-asan - Run tests with AddressSanitizer"
@echo " test-leaks - Run tests with macOS leaks tool"
@echo " bench - Run quick + load benchmarks"
@echo " bench-quick - Sequential benchmark (1000 requests)"
@echo " bench-load - Concurrent load test (5000 req, 50 concurrent)"
@echo " bench-server - Start server for manual wrk/ab testing"
@echo " bench-compare- Framework comparison (requires ab)"
@echo " clean - Remove build artifacts"
@echo " distclean - Remove all generated files"
@echo " help - Show this help message"