Each task's tests were run against a reference at its end state; the end states were replayed from master in order with the gate at each step (650 to 762 tests); each skeleton compiles against its tests and fails them. The reference is kept off this machine. Lessons T27 (every wait in a test has a limit) and T28 (mutate the reference before hand-over) come from this work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
4.5 KiB
M4a task 03: gatewayd.toml
Branch: m4a (run git switch m4a; git status --short must be empty, otherwise stop)
Commit subject: gatewayd: config, gatewayd.toml into a checked Config
Goal
gatewayd.toml says where Mattermost is, where the token comes from, who may talk to Boxmaker and
in which channels, and a few limits. It is our format: an unknown key anywhere is an error, and
a value that is wrong is refused at start with a message that names it. Spec section 3.
[mattermost]
url = "https://straylight.scylla-hammerhead.ts.net" # https or http; no path
ca_file = "/etc/boxmaker/extra-ca.pem" # optional; added to the system's roots
[secrets.mattermost_token]
credential = "mattermost-token" # exactly one of: credential, env, file
[allow]
users = ["abcdefghijklmnopqrstuvwxyz"] # Mattermost user ids (26 characters)
channels = [] # channels and group messages allowed, by id; default none
[loop]
socket = "" # empty: <home>/run/loop/loop.sock
[paths]
home = "/var/lib/boxmaker" # default: BOXMAKER_HOME, then /var/lib/boxmaker
[limits]
queue = 20
typing_every_ms = 3000
ping_every_ms = 30000
dead_after_ms = 60000
Files
- Copy:
crates/gatewayd/tests/config.rs,crates/gatewayd/tests/support/tmp.rs, and the skeletoncrates/gatewayd/src/config.rs - Modify:
crates/gatewayd/src/lib.rs(pub mod config;),docs/implementer-log.md
The skeleton
Every type is written, with its serde attributes: Config, MattermostConfig, SecretSpec,
SecretSource, AllowConfig, LoopConfig, Paths, Limits (with their defaults), ServerUrl,
ConfigError, and the constant MATTERMOST_TOKEN = "mattermost_token". Do not change them. The
functions are todo!(), each with its steps above it.
The messages, exactly
Config::problem returns the first problem, in this order:
| Problem | Message |
|---|---|
url fails parse_url |
parse_url's message: [mattermost] url "<url>" must be http:// or https://, a host, an optional port, and nothing else (the url with {:?}) |
ca_file not absolute |
[mattermost] ca_file "<path>" must be an absolute path ({:?}) |
no [secrets.mattermost_token] |
[secrets.mattermost_token] is missing |
a secret whose source() fails |
[secrets.<name>] <source's message> |
allow.users empty |
[allow] users is empty: a gateway that answers nobody is a mistake |
an id in allow.users or allow.channels that is not valid_id |
[allow] "<id>" is not a Mattermost id (26 characters of a-z and 0-9) ({:?}) |
| a limit that is 0 (checked in the order queue, typing_every_ms, ping_every_ms, dead_after_ms) | [limits] <name> must be at least 1 |
SecretSpec::source's messages:
| Case | Message |
|---|---|
| not exactly one of the three | needs exactly one of credential, env and file |
credential empty or with a byte that is not an ASCII letter, digit, _, . or - |
credential "<name>" is not a credential name (letters, digits, _ . -) |
env empty or with a byte that is not A-Z, 0-9 or _ |
env "<var>" is not a variable name (A-Z, 0-9, _) |
file not absolute |
file "<path>" must be an absolute path |
Config::token_source gives source() of mattermost_token, or [secrets.mattermost_token] is missing. ConfigError's Display is <path>: <error or message>.
Steps
- 1. Copy.
git switch m4a, thenmkdir -p crates/gatewayd/tests/support && cp docs/plans/M4a/files/crates/gatewayd/tests/config.rs crates/gatewayd/tests/ && cp docs/plans/M4a/files/crates/gatewayd/tests/support/tmp.rs crates/gatewayd/tests/support/ && cp docs/plans/M4a/files/crates/gatewayd/src/config.rs crates/gatewayd/src/. Addpub mod config;tocrates/gatewayd/src/lib.rs. - 2. See it fail.
cargo test -p gatewayd --test config. Expected: it compiles and 7 tests fail withnot yet implemented. - 3. Fill the functions one at a time:
valid_id,parse_url,SecretSpec::source,ConfigError'sfmt, then theConfigmethods.cargo check -p gatewaydafter each. - 4. See it pass.
cargo test -p gatewayd --test config. Expected: 7 passed. - 5. Run the gate.
cargo fmt --all, thenmake gate. Expected last line:gate: ok. - 6. Log and commit.
git add crates/gatewayd docs/implementer-log.md Cargo.lock && git commit
Done when
cargo test -p gatewayd --test configpasses;make gateprintsgate: ok.
Stop and report if
- A test wants a type changed. The types are the format; report instead.