Deploy MQTT test backend with private viewer and Gitea CI/CD
Test and deploy MQTT backend / test (push) Successful in 2m8s
Test and deploy MQTT backend / deploy (push) Successful in 18s

This commit is contained in:
2026-10-08 14:48:53 +03:30
commit 71ef622b4f
70 changed files with 7123 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
# 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.