Skip to content

Commit 52b45b7

Browse files
tridgeclaude
andcommitted
scripts: parallel test runner with -j option
Replace the bash logic in run_tests.sh with run_tests.py, which builds udpproxy and runs pytest twice (connections, then authentication) with optional -n J for pytest-xdist parallelism. run_tests.sh becomes a thin shim that activates the venv and execs the Python runner so existing CI and README invocations keep working. Add pytest-xdist to setup_ci.sh. The keys.tdb backup/restore dance in the old script is dropped: workers now use per-worker tmpdirs, so the repo-root keys.tdb is never touched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 151997e commit 52b45b7

3 files changed

Lines changed: 66 additions & 72 deletions

File tree

scripts/run_tests.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Test runner for UDPProxy.
4+
5+
Builds the udpproxy binary then runs the pytest suite. Pass -j N to run
6+
tests in parallel via pytest-xdist; each worker gets its own tmpdir and
7+
port pair so they don't collide.
8+
"""
9+
import argparse
10+
import os
11+
import subprocess
12+
import sys
13+
14+
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
15+
16+
17+
def run(cmd, **kwargs):
18+
print('+', ' '.join(cmd), flush=True)
19+
subprocess.check_call(cmd, **kwargs)
20+
21+
22+
def main():
23+
ap = argparse.ArgumentParser(description=__doc__)
24+
ap.add_argument('-j', type=int, default=1,
25+
help='parallel pytest workers via pytest-xdist (default: 1)')
26+
ap.add_argument('--no-build', action='store_true',
27+
help='skip the make step (use existing udpproxy binary)')
28+
args, extra = ap.parse_known_args()
29+
30+
os.chdir(REPO_ROOT)
31+
32+
if not args.no_build:
33+
print('=== Building UDPProxy ===')
34+
run(['make', 'clean'])
35+
run(['make', 'distclean'])
36+
run(['make', 'all'])
37+
38+
if not os.path.isfile('udpproxy'):
39+
sys.exit('ERROR: udpproxy binary not found')
40+
print('udpproxy binary built successfully')
41+
42+
pytest_base = [sys.executable, '-m', 'pytest', '-v']
43+
if args.j > 1:
44+
pytest_base += ['-n', str(args.j)]
45+
46+
# Two pytest invocations: connection tests first (uses test_server with a
47+
# live udpproxy), then authentication tests (mutates keys.tdb directly,
48+
# would clobber test_server's view if combined). Each invocation
49+
# parallelizes internally.
50+
print('\n=== Running Connection Tests ===')
51+
run(pytest_base + ['tests/test_connections.py'] + extra)
52+
53+
print('\n=== Running Authentication Tests ===')
54+
run(pytest_base + ['tests/test_authentication.py'] + extra)
55+
56+
print('\nAll tests completed.')
57+
58+
59+
if __name__ == '__main__':
60+
main()

scripts/run_tests.sh

Lines changed: 5 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,9 @@
11
#!/bin/bash
2+
# Thin wrapper that activates the project venv (if present) and forwards to
3+
# scripts/run_tests.py. The real logic lives in the Python runner so it can
4+
# accept -j for pytest-xdist parallelism.
25

3-
# Test runner script for UDPProxy
4-
# This script runs all tests with proper error handling
5-
6-
set -e # Exit on any error
7-
set -u # Exit on undefined variable
8-
set -o pipefail # Exit on pipe failure
9-
10-
# Ensure we're running from repository root
6+
set -e
117
cd "$(dirname "$0")/.."
12-
13-
echo "=== UDPProxy Test Runner ==="
14-
15-
# Cleanup function to restore database on exit
16-
cleanup() {
17-
echo ""
18-
echo "=== Cleanup ==="
19-
if [ -f "keys.tdb.backup" ]; then
20-
echo "Restoring original keys.tdb from backup"
21-
mv keys.tdb.backup keys.tdb
22-
else
23-
echo "Removing test database"
24-
rm -f keys.tdb
25-
fi
26-
}
27-
28-
# Set trap to ensure cleanup happens on normal exit too
29-
trap cleanup EXIT
30-
31-
# Activate virtual environment
32-
echo "Activating virtual environment..."
338
test -f venv/bin/activate && source venv/bin/activate
34-
35-
# Build UDPProxy
36-
echo "Building UDPProxy..."
37-
make clean
38-
make distclean
39-
make all
40-
41-
# Verify build
42-
if [ ! -f "./udpproxy" ]; then
43-
echo "ERROR: UDPProxy build failed - executable not found"
44-
exit 1
45-
fi
46-
47-
echo "✓ UDPProxy binary built successfully"
48-
49-
# Backup existing database if it exists
50-
echo "Setting up test database..."
51-
if [ -f "keys.tdb" ]; then
52-
echo "Backing up existing keys.tdb to keys.tdb.backup"
53-
mv keys.tdb keys.tdb.backup
54-
fi
55-
56-
# Create fresh test database
57-
echo "Initializing test database..."
58-
python3 keydb.py initialise
59-
60-
# Run tests
61-
echo ""
62-
echo "=== Running Tests ==="
63-
64-
echo ""
65-
echo "=== Running Connection Tests ==="
66-
pytest tests/test_connections.py -v -s
67-
68-
echo ""
69-
echo "=== Running Authentication Tests ==="
70-
pytest tests/test_authentication.py -v -s
71-
72-
echo ""
73-
echo "=== Test Summary ==="
74-
echo "All tests completed successfully!"
75-
echo "UDPProxy is ready for use."
9+
exec python3 scripts/run_tests.py "$@"

scripts/setup_ci.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ source venv/bin/activate
3636

3737
echo "Installing Python dependencies..."
3838
pip install --upgrade pip
39-
pip install pytest pymavlink
39+
pip install pytest pytest-xdist pymavlink
4040

4141
echo "Verifying tdb module accessibility..."
4242
python3 -c "import tdb; print('tdb module is available')"

0 commit comments

Comments
 (0)