Sign inSign up

ragilhadi/flux

By ragilhadi

•Updated about 1 month ago

Flux is a fast, Docker-only load testing tool written in Rust.

Image
0

1.7K

ragilhadi/flux repository overview

⁠⚔ Flux – High-Performance Container-Native Load Testing

GitHub

Flux is a fast, Docker-only load testing tool written in Rust.

No installation.
No dependencies.
Just Docker + YAML.


ā šŸš€ Features

  • Async or Sync load generation with Tokio
  • Multi-step scenarios with variable extraction
  • Multipart form-data with file upload support
  • JSON + HTML reports with beautiful charts
  • Real-time terminal display with progress bars
  • JSONPath extraction for chaining requests
  • Pure Docker usage - no local installation needed
  • High performance - built with Rust for maximum throughput

ā šŸ“¦ Quick Start

⁠1. Build the Docker image
docker build -t flux:latest .
⁠2. Create required folders
mkdir -p data results
⁠3. Put your files inside data/ (for multipart uploads)
echo "Sample file content" > data/sample.txt
⁠4. Create config.yaml

See the samples/ folder for examples.

⁠5. Run Flux
docker run --rm \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -v $(pwd)/data:/app/data \
  -v $(pwd)/results:/app/results \
  flux:latest

⁠🧩 Configuration

⁠Simple GET Request
target: "https://api.example.com/endpoint"
method: "GET"

headers:
  Accept: "application/json"

concurrency: 20
duration: "30s"
mode: "async"

output:
  json: "/app/results/output.json"
  html: "/app/results/report.html"
⁠POST with JSON Body
target: "https://api.example.com/users"
method: "POST"

headers:
  Content-Type: "application/json"

body: |
  {
    "username": "test",
    "email": "[email protected]"
  }

concurrency: 10
duration: "15s"
mode: "async"

output:
  json: "/app/results/output.json"
  html: "/app/results/report.html"
⁠Multipart Form-Data Upload
target: "https://api.example.com/upload"
method: "POST"

multipart:
  - type: "file"
    name: "avatar"
    path: "/app/data/avatar.png"

  - type: "field"
    name: "username"
    value: "john"

  - type: "field"
    name: "age"
    value: "25"

concurrency: 5
duration: "10s"
mode: "async"

output:
  json: "/app/results/output.json"
  html: "/app/results/report.html"
⁠Multi-Step Scenario with Variable Extraction
target: "https://api.example.com"

scenarios:
  - name: "login"
    method: "POST"
    url: "/auth/login"
    headers:
      Content-Type: "application/json"
    body: |
      {
        "username": "test",
        "password": "secret"
      }
    extract:
      token: "$.access_token"
      user_id: "$.user.id"

  - name: "get-profile"
    method: "GET"
    url: "/users/{{ user_id }}/profile"
    headers:
      Authorization: "Bearer {{ token }}"
    depends_on: "login"

  - name: "update-profile"
    method: "PUT"
    url: "/users/{{ user_id }}/profile"
    headers:
      Authorization: "Bearer {{ token }}"
      Content-Type: "application/json"
    body: |
      {
        "bio": "Updated bio"
      }
    depends_on: "get-profile"

concurrency: 10
duration: "30s"
mode: "async"

output:
  json: "/app/results/output.json"
  html: "/app/results/report.html"

ā šŸ“Š Configuration Options

⁠Global Settings
FieldTypeRequiredDefaultDescription
targetstringYes*-Base URL for requests
methodstringNoGETHTTP method (GET, POST, PUT, DELETE, etc.)
headersmapNo{}HTTP headers
bodystringNo-Request body (ignored if multipart is set)
multipartarrayNo-Multipart form data
scenariosarrayNo[]Multi-step scenarios
concurrencyintegerNo10Number of concurrent workers
durationstringNo30sTest duration (e.g., "30s", "5m", "1h")
modestringNoasyncExecution mode: "async" or "sync"
outputobjectYes-Output configuration

* Required if not using scenarios with full URLs

⁠Multipart Part
FieldTypeRequiredDescription
typestringYes"file" or "field"
namestringYesForm field name
pathstringYes (for file)File path (must be in /app/data)
valuestringYes (for field)Field value
⁠Scenario Step
FieldTypeRequiredDescription
namestringYesStep name
methodstringYesHTTP method
urlstringYesURL path or full URL
headersmapNoHTTP headers
bodystringNoRequest body
multipartarrayNoMultipart form data
extractmapNoJSONPath extraction rules
depends_onstringNoName of step this depends on
⁠Variable Extraction

Use JSONPath syntax to extract values from JSON responses:

extract:
  token: "$.access_token"
  user_id: "$.user.id"
  email: "$.user.email"

Then use extracted variables with {{ variable_name }} syntax:

headers:
  Authorization: "Bearer {{ token }}"
url: "/users/{{ user_id }}/profile"

ā šŸ“ˆ Metrics Collected

Flux collects comprehensive metrics for each request:

  • Latency (min, max, mean, p50, p90, p95, p99)
  • Throughput (requests per second)
  • Status codes distribution
  • Error rate and error messages
  • Request timestamps for timeline analysis

ā šŸ“„ Reports

⁠JSON Report

Contains full raw data and summary statistics:

{
  "summary": {
    "total_requests": 12430,
    "successful_requests": 12002,
    "failed_requests": 428,
    "throughput_rps": 414.33,
    "p50_latency_ms": 84,
    "p90_latency_ms": 152,
    "p99_latency_ms": 231,
    "error_rate": 3.44
  },
  "results": [...]
}
⁠HTML Report

Beautiful interactive report with:

  • Summary statistics cards
  • Latency distribution histogram
  • Latency over time line chart
  • Status code distribution pie chart
  • Percentiles table

ā šŸŽÆ Execution Modes

⁠Async Mode (Default)

Uses Tokio for maximum concurrency. Recommended for most use cases.

mode: "async"
concurrency: 100
⁠Sync Mode

Blocking workers with controlled request rate. Useful for testing rate limiting.

mode: "sync"
concurrency: 10

⁠🐳 Docker Usage

⁠Basic Usage
docker run --rm \
  -v ./config.yaml:/app/config.yaml \
  -v ./data:/app/data \
  -v ./results:/app/results \
  flux:latest
⁠With Custom Logging
docker run --rm \
  -e RUST_LOG=debug \
  -v ./config.yaml:/app/config.yaml \
  -v ./data:/app/data \
  -v ./results:/app/results \
  flux:latest
⁠Volume Mounts
  • /app/config.yaml - Configuration file (required)
  • /app/data - Directory for multipart files (optional)
  • /app/results - Directory for output reports (required)

ā šŸ”§ Building from Source

⁠Prerequisites
  • Rust
  • Docker (for containerized builds)
⁠Local Build
cargo build --release
./target/release/flux
⁠Docker Build
docker build -t flux:latest .

ā šŸ“ Examples

See the samples/ directory for complete examples:

  • simple-get.yaml - Basic GET request
  • simple-post.yaml - POST with JSON body
  • multipart-upload.yaml - File upload with multipart
  • scenario-auth.yaml - Multi-step authentication flow

ā šŸ› ļø Development

⁠Project Structure
flux/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ main.rs              # Entry point and orchestration
│   ā”œā”€ā”€ config.rs            # YAML configuration parsing
│   ā”œā”€ā”€ client.rs            # HTTP client wrapper
│   ā”œā”€ā”€ executor.rs          # Load test execution engine
│   ā”œā”€ā”€ metrics.rs           # Metrics collection
│   ā”œā”€ā”€ reporter.rs          # Report generation
│   ā”œā”€ā”€ ui.rs                # Terminal UI
│   └── templates/
│       └── report.html      # HTML report template
ā”œā”€ā”€ samples/
│   ā”œā”€ā”€ simple-get.yaml      # GET example
│   ā”œā”€ā”€ simple-post.yaml     # POST example
│   ā”œā”€ā”€ multipart-upload.yaml # Upload example
│   ā”œā”€ā”€ scenario-auth.yaml   # Scenario example
│   └── sample.txt           # Sample file
ā”œā”€ā”€ data/                    # Directory for multipart files
ā”œā”€ā”€ results/                 # Directory for output reports
ā”œā”€ā”€ Cargo.toml               # Rust dependencies
ā”œā”€ā”€ Cargo.lock               # Dependency lock file
ā”œā”€ā”€ Dockerfile               # Container image definition
ā”œā”€ā”€ Makefile                 # Build and development commands
ā”œā”€ā”€ build.sh                 # Build script
ā”œā”€ā”€ run-example.sh           # Run script
ā”œā”€ā”€ config.yaml              # Default configuration
ā”œā”€ā”€ README.md                # This file
ā”œā”€ā”€ IMPLEMENTATION.md        # Implementation details
└── QUICKSTART.md            # Quick start guide

For detailed implementation information, architecture, and technical decisions, see IMPLEMENTATION.md⁠.

⁠Running Tests
cargo test
⁠Code Style
cargo fmt
cargo clippy

ā šŸ¤ Contributing

Contributions are welcome! Please ensure:

  1. Code follows Rust best practices
  2. All tests pass
  3. Documentation is updated
  4. Commit messages are clear

ā šŸ’” Tips

  1. Start small: Begin with low concurrency and short duration
  2. Monitor resources: Watch CPU and memory usage
  3. Use async mode: For maximum throughput
  4. Check reports: HTML reports provide visual insights
  5. Test locally first: Validate config before production testing

Built with ā¤ļø using Rust

Tag summary

Content type

Image

Digest

sha256:f91fcf0a4…

Size

35.9 MB

Last updated

about 1 month ago

docker pull ragilhadi/flux