OOMlet β a lightweight, chaos-friendly QA and debugging Spring Boot application designed to help you test, stress, and harden your systems.
π³ Crack limits. Scramble resources. Cook up resilience.
- Quick Start
- API Endpoints
- Stress Testing Endpoints
- Connectivity & Delay Simulation
- Crash the Application
- Runtime Configuration
- Docker and Kubernetes Support
- Testing and Code Coverage
- Signal Handling
- Architecture Overview
- β Dynamic health check toggling (pass/fail)
- β Simulate arbitrary HTTP response codes
- β Memory and file handle stress testing endpoints
- β CPU load simulation
- β Graceful OS signal handling (SIGINT, SIGTERM, USR1, USR2)
- β Runtime log level adjustment (dynamic)
- β Crash with specific exit codes
- β Outbound connectivity tester (ping a URL)
- β Simulate response latency
- β Full Actuator integration
- β Code coverage enforcement (80% minimum)
- β Built for local development, Docker, and Kubernetes
- β Kind cluster configuration with ingress support
- β Production-ready Helm charts with autoscaling
- Java 17+ (Temurin recommended)
- Maven 3.8+ (no need to install if using the Maven Wrapper)
./mvnw clean packagejava -jar target/oomlet-0.0.8.jar(Optional) Override port:
SERVER_PORT=9090 java -jar target/oomlet-0.0.8.jar| Endpoint | Method | Purpose |
|---|---|---|
/actuator/health |
GET | Standard Spring Boot health check |
/api/health-toggle/enable |
POST | Set custom health indicator to pass |
/api/health-toggle/disable |
POST | Set custom health indicator to fail |
/api/status?responseCode=404 |
GET | Simulate specific HTTP status responses |
/api/open-files?count=100 |
GET | Stress test file descriptor limits |
/api/allocate-memory?bytes=104857600 |
GET | Allocate memory blocks to stress JVM heap |
/api/burn-cpu?millis=1000&threads=2 |
GET | Generate CPU load |
/api/ulimits |
GET | View OS resource limits (parsed ulimit) |
/api/logging/spring?level=DEBUG |
POST | Change Spring framework log level dynamically |
/api/crash?code=137 |
POST | Exit the process with specific code |
/api/ping?url=https://example.com |
GET | Test outbound connectivity to a URL |
/api/latency?delayMillis=1500 |
GET | Simulate response latency for timeout testing |
curl 'http://localhost:8080/api/allocate-memory?bytes=104857600'curl 'http://localhost:8080/api/open-files?count=100'curl 'http://localhost:8080/api/burn-cpu?millis=5000&threads=4'curl 'http://localhost:8080/api/ping?url=https://example.com'curl 'http://localhost:8080/api/latency?delayMillis=1500'Use this to simulate process failure and container exit.
curl -X POST 'http://localhost:8080/api/crash?code=137'curl -X POST 'http://localhost:8080/api/logging/spring?level=DEBUG'curl 'http://localhost:8080/api/logging/spring'You can limit or expand memory usage for stress tests:
JAVA_OPTS="-Xmx512m -Xms128m" java -jar target/oomlet-0.0.8.jardocker build -t oomlet:latest .docker run -p 8080:8080 oomlet:latestOOMlet includes comprehensive Kind cluster configuration for easy local Kubernetes testing with ingress support.
Option 1: One-Button Setup (Recommended)
./scripts/setup-kind.shOption 2: Manual Setup
-
Create Kind cluster with ingress support:
kind create cluster --name kind --config kind-config.yaml
-
Install NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s -
Deploy OOMlet with ingress:
helm install oomlet ./helm -f helm/values-kind.yaml
-
Add local DNS entry:
echo "127.0.0.1 oomlet.local" | sudo tee -a /etc/hosts
-
Test the deployment:
curl http://oomlet.local/actuator/health
kind-config.yaml: Kind cluster configuration with port mappings for ingresshelm/values-kind.yaml: Helm values optimized for Kind deployment with ingress enabled
scripts/setup-kind.sh: One-button setup script for complete Kind cluster and OOMlet deploymentscripts/cleanup-kind.sh: Cleanup script to remove cluster and DNS entries
With the Kind setup, you can easily test various failure scenarios:
# Test memory allocation (causes OutOfMemoryError)
curl "http://oomlet.local/api/allocate-memory?bytes=2147483648"
# Test application crash (simulates pod failure)
curl -X POST "http://oomlet.local/api/crash?code=137"
# Test CPU stress
curl "http://oomlet.local/api/burn-cpu?millis=5000&threads=4"
# Test file handle limits
curl "http://oomlet.local/api/open-files?count=100"- β
One-button setup with
./scripts/setup-kind.sh - β
Direct ingress access on
http://oomlet.local(no port forwarding) - β Production-like environment for testing Kubernetes features
- β
Easy cleanup:
./scripts/cleanup-kind.sh - β Automatic pod recovery testing
- β Load balancer behavior simulation
β Designed to be liveness- and readiness-probe friendly. β Docker image built for minimal size and startup speed. β Full Kubernetes ingress support with automatic failover.
| Variable | Purpose | Example |
|---|---|---|
SERVER_PORT |
Override server port | SERVER_PORT=9090 |
JAVA_OPTS |
Pass JVM options | JAVA_OPTS="-Xmx512m" |
Run unit and integration tests:
./mvnw clean verifyOpen coverage report:
open target/site/jacoco/index.htmlView live coverage:
- GitHub Pages: https://trcjr.github.io/oomlet
- Codecov: https://codecov.io/gh/trcjr/oomlet
β Enforced 80%+ line coverage. β Build fails if coverage threshold not met. β CI/CD runs on each push via GitHub Actions.
This project enforces 80% minimum line coverage using JaCoCo.
Fail the build on low coverage by editing pom.xml:
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>Or use .codecov.yml in root:
coverage:
status:
project:
default:
target: 80%
threshold: 1%All GitHub Actions workflows in this project follow strict rules for consistency and reliability. This includes:
- β
Git short hashes must be set using
git rev-parse --short HEADand passed via$GITHUB_OUTPUT - β
Helm chart versions must be valid SemVer using the
-dev.<short_hash>format - β CI/CD steps are explicitly structured to avoid flakiness and ensure reproducibility
OOMlet handles:
- SIGINT (
Ctrl+C) - SIGTERM (
docker stop,kubectl delete pod) - SIGHUP, SIGQUIT, SIGUSR1, SIGUSR2
Gracefully shuts down or logs custom signals.
- SIGUSR1 β logs current heap usage and active memory state
- SIGUSR2 β logs thread dump and internal diagnostics
This project uses a comprehensive security approach with multiple layers of protection:
- Dependabot: Automated dependency updates with security scanning
- Weekly updates for Maven, GitHub Actions, and Docker dependencies
- Daily security updates for critical vulnerabilities
- Automatic PR creation with proper labeling and review assignment
- Groups minor and patch updates to reduce PR noise
- CodeQL Analysis: Static code analysis for Java vulnerabilities
- Trivy Container Scanning: Docker image vulnerability scanning
- GitHub Security Advisories: Integration with GitHub's security database
The security scan workflow runs:
- Scheduled: Every Sunday at midnight UTC
- Manual: Via workflow dispatch
- Docker Scanning: Container image vulnerability analysis
- Code Scanning: Static analysis with CodeQL
- GitHub Security tab integration
- Dependabot alerts for vulnerable dependencies
- CodeQL alerts for code vulnerabilities
- Container scanning alerts for image vulnerabilities
ββββββββββββββββββββββββββββββ
β Client / User β
βββββββββββββββ¬βββββββββββββββ
β
HTTP Requests
β
βββββββββββββββΌβββββββββββββββ
β Spring Boot Server β
βββββββββββββββ¬βββββββββββββββ
β
βββββββββββΌβββββββββββ¬βββββββββββββββ¬βββββββββββββββ¬ββββββββββββββ
β β β β β
βββββΌββββ ββββββΌβββββ ββββββΌβββββ βββββββββΌββββββ ββββββββΌβββββ
βstatusβ βopen-filesββallocate β β /ulimits β βactuator β
β β β ββmemory β β burn-cpu β β health, etcβ
ββββββββ βββββββββββββββββββββββ βββββββββββββββ βββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββ
β SignalHandlerService β
βββββββββββ¬ββββββββββββββββββββ
βΌ
Graceful Shutdown
MIT β see LICENSE
We welcome PRs and issues. Start with CONTRIBUTING.md
Look for issues labeled good first issue to help out!