momus-cli 0.9.2

Momus API test harness — CLI runner
# momus-cli

[![Crates.io](https://img.shields.io/crates/v/momus-cli.svg)](https://crates.io/crates/momus-cli)
[![Docs.rs](https://img.shields.io/docsrs/momus-cli)](https://docs.rs/momus-cli)

**Momus API test harness — CLI runner.**

## What is this?

`momus-cli` is the command-line binary for the Momus API test harness. It provides a unified interface to all Momus capabilities: running and validating test plans, starting a mock server, load testing, fuzzing, chaos engineering, contract testing, security scanning, diff testing, and converting API descriptions into test plans.

## Commands

```text
Usage: momus <COMMAND>

Commands:
  run          Run a test plan from a JSON file
  validate     Validate a test plan JSON file
  mock         Start a mock server for testing
  bench        Load test a plan (steady, max-throughput, or soak)
  fuzz         Fuzz test a plan with payload mutations
  chaos        Run chaos experiments against a plan
  convert      Convert an API description into a test plan
  contract     Validate API responses against an OpenAPI/GraphQL spec
  guard        Security scan a plan for common vulnerabilities
  diff         Diff responses between two environments
  init         Generate a skeleton test plan or config file
  plan         Show a human-readable summary of a test plan
  completions  Generate shell completion scripts
  docs         Open the Momus documentation in your browser
  fhir         FHIR-specific operations (mock, validate, generate, openapi, upload, delete)
```

### `momus run`

```bash
# Run with default output directory (./output/run)
momus run plan.json

# Override base URL
momus run plan.json --base-url http://other-server:3000

# Custom output directory
momus run plan.json --output ./results

# Dry-run: validate and print the resolved requests without sending anything
momus run plan.json --dry-run
```

Every command writes its reports to a dedicated subfolder under `./output/` by
default, so all results live in one place:

| Command | Default output |
|---------|----------------|
| `run` | `./output/run/` |
| `bench` | `./output/bench/` |
| `fuzz` | `./output/fuzz/` |
| `chaos` | `./output/chaos/` |
| `contract` | `./output/contract/` |
| `guard` | `./output/guard/` |
| `diff` | `./output/diff/` |
| `plan` | `./output/plan/` |
| `fhir generate` | `./output/fhir/` |

Override any of these with `--output <path>` (or the `output` key in the config
file).

`--dry-run` parses and validates the plan, resolves templates where statically
possible (e.g. `{base_url}`, `{env.*}`), and prints the resolved request list
(method, URL, headers, body size, assertion count) without making any network
requests. Sensitive headers (Authorization, Cookie, token, etc.) are redacted.
It exits non-zero if the plan fails validation (e.g. a relative URL with no
`base_url` set).

### `momus validate`

```bash
momus validate plan.json
# ✓ Valid test plan: 'health check'
#   Total tests: 3
#   Steps: 1
```

### `momus mock`

```bash
momus mock --port 8091
# Momus mock server listening on http://127.0.0.1:8091
```

### `momus bench`

```bash
# Steady load: 50 concurrent users for 60 seconds
momus bench plan.json --concurrency 50 --duration 60

# Override base URL
momus bench plan.json --concurrency 100 --duration 30 --base-url http://staging:8080

# Max-throughput: ramp concurrency until error rate or P99 latency threshold is breached
momus bench plan.json --mode max-throughput --min-concurrency 10 --max-concurrency 200 --step 10

# Soak: sustained load for a long duration
momus bench plan.json --mode soak --concurrency 20 --duration 3600

# Warmup requests before recording (excluded from stats)
momus bench plan.json --concurrency 50 --duration 60 --warmup 100

# Machine-readable JSON summary output
momus bench plan.json --concurrency 50 --duration 60 --format json
```

`bench` supports three modes: `steady` (default), `max-throughput`, and `soak`.
Latency percentiles (P50/P90/P95/P99) are recorded with an HDR histogram and
warmup requests are excluded from the reported statistics. `--format json`
emits a versioned (`schema_version: 1`) machine-readable report suitable for
CI dashboards and trend tracking. Pressing Ctrl+C stops the benchmark early and
still prints a partial report with whatever results were collected.

### `momus fuzz`

```bash
# Generate 5000 mutations
momus fuzz plan.json --iterations 5000

# Override base URL
momus fuzz plan.json --iterations 10000 --base-url http://staging:8080
```

### `momus chaos`

```bash
# Run chaos experiments against a plan
momus chaos plan.json

# Override base URL
momus chaos plan.json --base-url http://staging:8080
```

### `momus convert`

```bash
# Convert a cURL command into a test plan
momus convert curl 'curl -X POST https://api.example.com/users -H "Content-Type: application/json" -d "{\"name\":\"test\"}"'

# Convert a HAR file into a test plan
momus convert har traffic.har

# Convert an OpenAPI spec into a test plan
momus convert openapi spec.yaml

# Convert a Postman collection into a test plan
momus convert postman collection.json

# Convert a GraphQL schema into a test plan
momus convert graphql schema.graphql

# Convert a gRPC proto into a test plan
momus convert grpc service.proto

# Convert a FHIR IG package into a test plan
momus convert fhir ig.tar.gz

# Generate bulk FHIR test data (NDJSON) from an IG package
momus fhir generate ig.tar.gz --count 10 --output ./fhir-data

# Upload the generated data to a repository endpoint before running tests.
# The repository endpoint may differ from the FHIR server under test, and
# accepts resources directly via PUT (default) with basic auth:
momus fhir upload --data-dir ./fhir-data/data --endpoint https://repo.example.com/fhir \
  --username user --password pass --method PUT

# Delete the uploaded resources (cleanup after tests):
momus fhir delete --data-dir ./fhir-data/data --endpoint https://repo.example.com/fhir \
  --username user --password pass
```

### `momus contract`

```bash
# Validate responses against an OpenAPI spec
momus contract plan.json --spec openapi.yaml

# Validate responses against a GraphQL schema
momus contract plan.json --spec schema.graphql
```

### `momus guard`

```bash
# Security scan a plan
momus guard plan.json

# Override base URL
momus guard plan.json --base-url http://staging:8080
```

### `momus diff`

```bash
# Diff responses between two environments
momus diff plan.json --baseline https://api-v1.example.com --target https://api-v2.example.com
```

### `momus completions`

```bash
# Generate shell completions and install them
momus completions bash > ~/.local/share/bash-completion/completions/momus.bash
momus completions zsh > "${fpath[1]}/_momus"
momus completions fish > ~/.config/fish/completions/momus.fish
```

`completions` supports any shell `clap_complete` knows about (bash, zsh, fish,
elvish, powershell, nushell).

### `momus docs`

```bash
momus docs
# Opening documentation: https://docs.rs/momus
```

Opens the Momus documentation (https://docs.rs/momus) in your default browser.
If a browser cannot be opened (e.g. headless environment), the URL is printed
instead and the command never fails hard.

### `momus fhir`

FHIR-specific operations for working with FHIR Implementation Guide packages.

```bash
# Start a FHIR mock server with CRUD + search support
momus fhir mock --port 8091

# Validate a JSON resource against a profile from an IG package
momus fhir validate ig-package.tgz --resource Patient.json --profile http://example.org/StructureDefinition/TestPatient

# Validate with auto-detected profile (by resourceType)
momus fhir validate ig-package.tgz --resource Patient.json

# Generate bulk FHIR test data (NDJSON) from an IG package
momus fhir generate ig-package.tgz --count 10 --output ./output/fhir

# Generate an OpenAPI 3.x spec (YAML) from a FHIR IG package
momus fhir openapi ig-package.tgz

# Generate a JSON spec and write it to a file
momus fhir openapi ig-package.tgz --format json --output openapi.json

# Generate an OpenAPI spec from a live FHIR server's CapabilityStatement (/metadata)
momus fhir openapi --base-url https://fhir.example.org/fhir
```

## Configuration

Momus is configured with a single TOML file. Each sub-command reads its own
section (`[run]`, `[bench]`, `[fuzz]`, `[chaos]`, `[contract]`, `[guard]`,
`[diff]`, `[plan]`), and a `[global]` section provides cross-cutting defaults
inherited by all commands. See the commented `config.toml` at the repo root for
a fully documented template.

### Discovery

The config file is located from, in order:

1. `--config <path>` (explicit)
2. `$MOMUS_CONFIG` (environment variable)
3. `./momus.toml`
4. `./.momus.toml`
5. `~/.config/momus/config.toml`

If no config file is found, built-in defaults are used.

### Precedence

Values are resolved with the following precedence (highest wins):

```
CLI flags > environment variables > config file > plan > built-in defaults
```

For example, `momus run plan.json --base-url https://api.example.com` overrides
both the `[run]`/`[global]` `base_url` in the config file and the plan's
`base_url`.

### Environment-variable interpolation

Any string value in the config file may reference an environment variable with
`$VAR` or `${VAR}` syntax:

```toml
[global]
base_url = "$API_URL"
```

Unset variables are left as-is so you see the placeholder in error messages
rather than a silent empty string.

### Cross-cutting settings

The `[global]` section covers settings shared by all commands:

```toml
[global]
base_url = "http://localhost:8080"
timeout_secs = 60
output = "./output"              # base directory; commands write to ./output/<command>/
output_format = "html"          # auto, text, html, junit, json

[global.headers]
Authorization = "Bearer your-token-here"

[global.retry]
max_retries = 3
backoff_secs = 2

[global.tls]
insecure_skip_verify = true     # dev only

# proxy = "http://proxy.example.com:3128"
```

### Environment profiles

Per-environment overrides are declared as `[env.<name>]` sections and applied
with the `MOMUS_ENV` environment variable:

```toml
[env.staging]
base_url = "https://staging.example.com"
timeout_secs = 60
```

```bash
MOMUS_ENV=staging momus run plan.json
```

### Per-command sections

Each sub-command reads its own section without duplicating parsing logic. For
example, `[bench]` configures load testing and `[diff]` configures regression
comparison:

```toml
[bench]
mode = { type = "Steady", concurrency = 20, duration_secs = 60 }
warmup_requests = 10

[diff]
baseline_url = "https://prod.example.com"
target_url = "https://staging.example.com"
diff_headers = true
diff_bodies = true
diff_status = true
```

Unknown fields are rejected with a clear error (so typos fail fast), and a
missing config file reports the path that was attempted.

---

Part of the [Momus](https://github.com/jlcoulter/momus) project — a generic API test harness with a composable assertion AST.