Skip to content

Asnyc testing #604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Aug 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions .github/workflows/asynctest.yml.inactive
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# ===============================================================
# 🔄 Async Safety & Performance Testing
# ===============================================================
#
# - runs the async safety and performance tests across multiple Python versions
# - includes linting, debugging, profiling, benchmarking, and validation
# - uploads the test artifacts as build artifacts
# - performs a performance regression check
# ---------------------------------------------------------------

name: Tests & Coverage

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
# schedule:
# - cron: '42 3 * * 1' # Monday 03:42 UTC

permissions:
contents: write # needed *only* if the badge-commit step is enabled
checks: write
actions: read

jobs:
async-testing:
name: 🔄 Async Safety & Performance Testing
runs-on: ubuntu-latest
needs: [test]

strategy:
fail-fast: false
matrix:
python: ["3.11", "3.12"]

steps:
- name: ⬇️ Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: 🐍 Setup Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: pip

- name: 📦 Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .[dev]
pip install flake8-async flake8-bugbear pytest-asyncio snakeviz aiomonitor

- name: 🔍 Run async linting
run: |
make async-lint

- name: 🐛 Run async debug tests
run: |
make async-debug

- name: 📊 Generate performance profiles
run: |
make profile

- name: ⚡ Run async benchmarks
run: |
make async-benchmark

- name: ✅ Validate async patterns
run: |
make async-validate

- name: 📎 Upload async test artifacts
uses: actions/upload-artifact@v4
with:
name: async-test-results
path: |
async_testing/reports/
async_testing/profiles/
retention-days: 30

- name: 📈 Performance regression check
run: |
python async_testing/check_regression.py \
--current async_testing/profiles/latest.prof \
--baseline async_testing/profiles/baseline.prof \
--threshold 20 # 20% regression threshold
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
python3 -m pip install --upgrade pip
# install the project itself in *editable* mode so tests import the same codebase
# and pull in every dev / test extra declared in pyproject.toml
pip install -e .[dev]
pip install -e .[dev,asyncpg]
# belt-and-braces - keep the core test tool-chain pinned here too
pip install pytest pytest-cov pytest-asyncio coverage[toml]

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
CLAUDE.local.md
.aider*
.scannerwork
llms-full.txt
aider*
.aider*
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ pytest -m "not slow"
# To test everything:

make autoflake isort black pre-commit
make interrogate doctest test smoketest lint-web flake8 bandit pylint
make doctest test htmlcov smoketest lint-web flake8 bandit interrogate pylint verify

# Rules
- When using git commit always add a -s to sign commits
Expand Down
5 changes: 4 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ include *.yml
include *.json
include *.sh
include *.txt
recursive-include async_testing *.py
recursive-include async_testing *.yaml

# 3️⃣ Tooling/lint configuration dot-files (explicit so they're not lost)
include .env.make
Expand Down Expand Up @@ -73,7 +75,8 @@ prune *.egg-info
prune charts
prune k8s
prune .devcontainer

exclude CLAUDE.*
exclude llms-full.txt

# Exclude deployment, mcp-servers and agent_runtimes
prune deployment
Expand Down
91 changes: 91 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3705,6 +3705,97 @@ pip-audit: ## 🔒 Audit Python dependencies for CVEs
python3 -m pip install --quiet --upgrade pip-audit && \
pip-audit --strict || true"



## --------------------------------------------------------------------------- ##
## Async Code Testing and Performance Profiling
## --------------------------------------------------------------------------- ##
.PHONY: async-test async-lint profile async-monitor async-debug profile-serve

ASYNC_TEST_DIR := async_testing
PROFILE_DIR := $(ASYNC_TEST_DIR)/profiles
REPORTS_DIR := $(ASYNC_TEST_DIR)/reports
VENV_PYTHON := $(VENV_DIR)/bin/python

async-test: async-lint async-debug
@echo "🔄 Running comprehensive async safety tests..."
@mkdir -p $(REPORTS_DIR)
@PYTHONASYNCIODEBUG=1 $(VENV_PYTHON) -m pytest \
tests/ \
--asyncio-mode=auto \
--tb=short \
--junitxml=$(REPORTS_DIR)/async-test-results.xml \
-v

async-lint:
@echo "🔍 Running async-aware linting..."
@$(VENV_DIR)/bin/ruff check mcpgateway/ tests/ \
--select=F,E,B,ASYNC \
--output-format=github
@$(VENV_DIR)/bin/flake8 mcpgateway/ tests/ \
--extend-select=B,ASYNC \
--max-line-length=100
@$(VENV_DIR)/bin/mypy mcpgateway/ \
--warn-unused-coroutine \
--strict

profile:
@echo "📊 Generating async performance profiles..."
@mkdir -p $(PROFILE_DIR)
@$(VENV_PYTHON) $(ASYNC_TEST_DIR)/profiler.py \
--scenarios websocket,database,mcp_calls \
--output $(PROFILE_DIR) \
--duration 60
@echo "🌐 Starting SnakeViz server..."
@$(VENV_DIR)/bin/snakeviz $(PROFILE_DIR)/combined_profile.prof \
--server --port 8080

profile-serve:
@echo "🌐 Starting SnakeViz profile server..."
@$(VENV_DIR)/bin/snakeviz $(PROFILE_DIR) \
--server --port 8080 --hostname 0.0.0.0

async-monitor:
@echo "👁️ Starting aiomonitor for live async debugging..."
@$(VENV_PYTHON) $(ASYNC_TEST_DIR)/monitor_runner.py \
--webui_port 50101 \
--console_port 50102 \
--host localhost \
--console-enabled

async-debug:
@echo "🐛 Running async tests with debug mode..."
@PYTHONASYNCIODEBUG=1 $(VENV_PYTHON) -X dev \
-m pytest tests/ \
--asyncio-mode=auto \
--capture=no \
-v

async-benchmark:
@echo "⚡ Running async performance benchmarks..."
@$(VENV_PYTHON) $(ASYNC_TEST_DIR)/benchmarks.py \
--output $(REPORTS_DIR)/benchmark-results.json \
--iterations 1000

profile-compare:
@echo "📈 Comparing performance profiles..."
@$(VENV_PYTHON) $(ASYNC_TEST_DIR)/profile_compare.py \
--baseline $(PROFILE_DIR)/combined_profile.prof \
--current $(PROFILE_DIR)/mcp_calls_profile.prof \
--output $(REPORTS_DIR)/profile-comparison.json

async-validate:
@echo "✅ Validating async code patterns..."
@$(VENV_PYTHON) $(ASYNC_TEST_DIR)/async_validator.py \
--source mcpgateway/ \
--report $(REPORTS_DIR)/async-validation.json

async-clean:
@echo "🧹 Cleaning async testing artifacts..."
@rm -rf $(PROFILE_DIR)/* $(REPORTS_DIR)/*
@pkill -f "aiomonitor" || true
@pkill -f "snakeviz" || true

## --------------------------------------------------------------------------- ##
## Gitleaks (Go binary - separate installation)
## --------------------------------------------------------------------------- ##
Expand Down
Loading
Loading