Open-source performance testing framework built on Python Locust.
Aegis-Perf provides a structured, scalable approach to API performance testing with pluggable authentication, automated reporting, performance budgets, and CI/CD integration.
- Abstract base users for REST and GraphQL APIs with pluggable auth strategies
- Performance budgets with automated pass/fail evaluation
- Enhanced HTML reports with Plotly charts, endpoint metrics, and variance analysis
- Optional AI root-cause analysis via Claude (Anthropic API or AWS Bedrock)
- Post-run pipeline: parse CSV, generate reports, push to InfluxDB, notify Slack
- Makefile-driven workflow for local and CI/CD execution
- Docker Compose stack for distributed testing with InfluxDB + Grafana
- Kubernetes/Helm support for production-scale load generation
- CI/CD templates for GitHub Actions and GitLab CI
aegis-perf/
├── aegis/ # Core framework
│ ├── base/ # RestUser, GraphQLUser base classes
│ ├── auth/ # Pluggable auth strategies
│ ├── config/ # YAML + env var config management
│ ├── data/ # Faker-based test data factories
│ ├── reporting/ # CSV parser, HTML reports, LLM analyzer
│ ├── metrics/ # InfluxDB metrics push
│ ├── notifications/ # Slack notifications
│ └── plugins/ # Custom Locust event listeners
├── testplans/ # Test plans (one package per target)
│ └── reqres/ # Demo tests against reqres.in
├── config/ # Configuration files
├── docker/ # Docker + Compose
├── k8s/ # Helm chart for Kubernetes
└── ci/ # CI/CD pipeline templates
cd aegis-perf
pip install -e ".[all,dev]"Opens the Locust web UI at http://localhost:8089:
make testmake test-headlessOverride defaults via environment variables:
AEGIS_USERS=20 AEGIS_RUN_TIME=5m make test-headlessmake test-with-reportThis runs the test, parses CSVs, and generates an enhanced HTML report at o/report/enhanced_report.html.
target:
host: "https://reqres.in"
auth:
strategy: "no_auth" # no_auth | bearer_token | api_key
load:
users: 10
spawn_rate: 2
run_time: "2m"
budgets:
failure_rate: 1.0 # max failure rate (%)
p95_response_time: 2000 # max P95 (ms)
avg_response_time: 1000 # max average (ms)
min_rps: 5 # min throughputEnvironment variables override YAML values:
| Variable | Description | Default |
|---|---|---|
AEGIS_TARGET_HOST |
Target API base URL | https://reqres.in |
AEGIS_AUTH_STRATEGY |
Auth strategy name | no_auth |
AEGIS_API_TOKEN |
Bearer token (for bearer_token strategy) |
- |
AEGIS_USERS |
Number of concurrent users | 10 |
AEGIS_SPAWN_RATE |
User spawn rate per second | 2 |
AEGIS_RUN_TIME |
Test duration | 2m |
from locust import task, between
from aegis.base import RestUser
from aegis.data.factory import UserDataFactory
class MyAPITests(RestUser):
host = "https://your-api.com"
wait_time = between(0.5, 1.5)
@task(10)
def list_items(self):
self._get("/api/items", name="List Items")
@task(5)
def create_item(self):
payload = UserDataFactory.create_user()
self._post("/api/items", payload=payload, name="Create Item")from locust import task
from aegis.base import GraphQLUser
class MyGraphQLTests(GraphQLUser):
host = "https://your-graphql-api.com"
graphql_endpoint = "/graphql"
@task
def list_users(self):
self._query(
query='{ users { id name email } }',
name="List Users",
)from aegis.base import RestUser
from aegis.auth import BearerTokenAuth
class AuthenticatedTests(RestUser):
host = "https://api.example.com"
auth_strategy = BearerTokenAuth(token_env_var="MY_API_TOKEN")Define SLA thresholds in config/performance_budgets.json:
{
"default_budgets": {
"failure_rate": 1.0,
"p95_response_time": 2000,
"avg_response_time": 1000,
"min_rps": 5
},
"per_endpoint_budgets": {
"List Users": {
"p95_response_time": 1500
}
}
}The enhanced report automatically evaluates these budgets and shows PASS/FAIL status.
Enable LLM root-cause analysis in config/performance_budgets.json:
{
"llm_config": {
"enabled": true,
"provider": "anthropic"
}
}Set your API key:
export ANTHROPIC_API_KEY=your-keyRun with deep analysis:
DEEP_ANALYSIS=true make test-with-reportRun a distributed Locust cluster with monitoring:
cd docker
docker compose up -dThis starts:
- Locust master (port 8089) + 2 workers
- InfluxDB (port 8086)
- Grafana (port 3000)
| Target | Description |
|---|---|
make install |
Install all dependencies |
make test |
Run with Locust web UI |
make test-headless |
Run headless with CSV/HTML output |
make test-with-report |
Full pipeline: test + parse + report |
make parse |
Parse Locust CSVs to JSON |
make report |
Generate enhanced HTML report |
make push |
Push metrics to InfluxDB |
make notify |
Send summary to Slack |
make lint |
Run ruff linter |
make unit-test |
Run pytest unit tests |
make clean |
Remove output artifacts |
from aegis.auth.base import AuthStrategy
class OAuth2Auth(AuthStrategy):
def authenticate(self, host: str) -> None:
# Implement OAuth2 flow
self._token = obtain_token(host)
def get_headers(self) -> dict[str, str]:
return {
"Content-Type": "application/json",
"Authorization": f"Bearer {self._token}",
}from aegis.data.factory import fake
class OrderDataFactory:
@staticmethod
def create_order() -> dict:
return {
"product_id": fake.random_int(1, 1000),
"quantity": fake.random_int(1, 10),
"shipping_address": fake.address(),
}MIT