Files
mqtt-5-test/docs/CONFIGURATION.md
T
Ryan 71ef622b4f
Test and deploy MQTT backend / test (push) Successful in 2m8s
Test and deploy MQTT backend / deploy (push) Successful in 18s
Deploy MQTT test backend with private viewer and Gitea CI/CD
2026-10-08 14:48:53 +03:30

74 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Configuration and offline CLI
Requires Go 1.27.1. The CLI supports offline `check-config`, MQTT `observe`, and `command ping|get_version`. The device simulator is available separately; see [RUNNING.md](RUNNING.md) for TLS/plaintext commands and visible message flow. An optional read-only HTTP/SSE viewer is available in observe mode; see [RUNNING.md](RUNNING.md).
```sh
rtk go run ./cmd/test-mqtt5 --help
rtk go run ./cmd/test-mqtt5 --config config.example.toml check-config
rtk go run ./cmd/test-mqtt5 --config config.example.toml --device-id lab-001 --log-level debug check-config
rtk go build -buildvcs=false -o bin/test-mqtt5 ./cmd/test-mqtt5
```
Flags precede the subcommand. `-buildvcs=false` avoids stamping errors when this folder sits inside an unavailable/incomplete parent Git checkout. It does not alter Git state.
## Precedence and environment mapping
Defaults < optional TOML file < environment < explicitly supplied flags. No file is loaded automatically. An explicit missing/malformed file fails. Unknown keys and invalid types fail, including in empty TOML tables. Relative file paths resolve against the process working directory.
Every key in [config.example.toml](../config.example.toml) has an environment equivalent: prepend `TEST_MQTT5_`, uppercase, and replace the dot between section/key with `__`. Preserve single underscores in field names.
| TOML key | Environment name | Example |
| --- | --- | --- |
| mqtt.url | TEST_MQTT5_MQTT__URL | tls://localhost:8883 |
| mqtt.client_id | TEST_MQTT5_MQTT__CLIENT_ID | rm5-lab-observer-01 |
| mqtt.password | TEST_MQTT5_MQTT__PASSWORD | Provide a test-only secret outside tracked files |
| mqtt.password_file | TEST_MQTT5_MQTT__PASSWORD_FILE | secrets/backend-password |
| mqtt.session_expiry | TEST_MQTT5_MQTT__SESSION_EXPIRY | 5m |
| tls.ca_file | TEST_MQTT5_TLS__CA_FILE | certs/ca.pem |
| topics.device_id | TEST_MQTT5_TOPICS__DEVICE_ID | sim-001 |
| logging.format | TEST_MQTT5_LOGGING__FORMAT | json |
| simulator.ack_delay | TEST_MQTT5_SIMULATOR__ACK_DELAY | 0s |
| web.enabled | TEST_MQTT5_WEB__ENABLED | false |
All fields and defaults are listed in the example TOML. Durations must be strings with units (`0s`, `5s`, `10m`); bare numbers and overflowing values fail. Booleans accept true/false. Integers reject fractional values. Empty environment values override previous values, including clearing a password; nonempty password and password_file cannot be combined.
## Validation limits
- Broker URL defaults to verified `tls://host:port`. Test-only `mqtt://host:port` requires `mqtt.allow_plaintext=true` (or --allow-plaintext). Port is 1–65535; embedded credentials/path/query/fragment are prohibited.
- Device/client IDs and namespace segments use safe identifiers; namespace remains under robot-market/test/v1.
- QoS is 0 or 1. Session expiry is whole seconds, 0–4294967295; keepalive is whole seconds, 1–65535.
- Positive operation/connection/shutdown intervals are bounded; reconnect_max is at most 30s and >= reconnect_min.
- Command lifetime is whole seconds, 1–60; dedup retention must exceed it.
- Payload limit is 256–16384 bytes; preview is 64–4096 and no larger than payload limit.
- Pending/queue/history/dedup capacities are 1–10000; viewer count is 1–8.
- Viewer address is 127.0.0.1 with a valid port. The viewer binds only to 127.0.0.1; max viewers is 1–8 and each viewer queue is 1–256 events.
- Certificate/key must be paired. Configured secret/certificate paths must reference readable, nonempty regular files up to 1 MiB.
## Output and limitations
Success uses configured text or JSON slog output, with `event=config_valid`, `network_checked=false` and `credentials_checked=false`. Success remains visible at the configured level, including warn/error. Invalid configuration/CLI errors go to stderr with exit 1/2 and omit supplied values. Help exits 0. Cancellation exits 1.
Empty test passwords are allowed for offline validation. This check does not load/validate password-file contents, parse certificates, establish trust, verify the broker hostname, authenticate, or test MQTT compatibility. Runtime modes parse certificates, authenticate, and check MQTT transport acknowledgements. CA paths are optional; TLS uses system trust plus a configured test CA, with hostname verification always enabled.
Keep real credentials in ignored config.local.toml, environment or secrets files. Never log a complete Config. Default previews of MQTT payloads are allowlisted as described in CONTRACTS.md.
## Checks
```sh
rtk gofmt -l cmd internal
rtk go vet ./...
rtk go test ./...
rtk go test -race ./...
```
During Sprint 1 verification, module/build caches used `/tmp/test-mqtt5-mod` and `/tmp/test-mqtt5-build`; these are temporary local caches, not required for ordinary usage.
Additional test observation settings:
- `topics.observe_devices`: comma-separated additional device IDs, maximum 16; observe mode only. Each device is subscribed using exact category topics. `topics.device_id` remains the target for single-device command mode.
- `logging.raw_payloads`: false by default; enables bounded raw MQTT payload display in logs and browser for test diagnostics. Docker observer explicitly enables it. Invalid contracts still produce validation errors and never imply successful compatibility.
`topics.observe_all=true` is observe-mode-only: subscribe to `<namespace>/#`, record raw payloads and skip all JSON contract validation. Compose enables this setting for functional testing.
`receipts.enabled=true` enables asynchronous backend receipt ACK publication in raw observe mode only. The reply queue uses limits.inbound_queue; publication uses deadlines.operation. It does not introduce JSON admission checks.