Skip to content

test(e2e): cover the hand-edited definition path - #1123

Merged
edwin-zvs merged 1 commit into
mainfrom
e2e-service-watcher
Aug 1, 2026
Merged

test(e2e): cover the hand-edited definition path#1123
edwin-zvs merged 1 commit into
mainfrom
e2e-service-watcher

Conversation

@edwin-zvs

Copy link
Copy Markdown
Contributor

Why

crates/config/services/*.toml is a documented, hand-editable surface, and #1119 made edits there apply live. But that path had no automated coverage — I verified it by hand and said so in that PR.

It resists unit testing by nature: a definition file has no IPC call to assert against, and the only evidence an edit applied is that the daemon's listeners changed. That needs a real daemon and a real socket, so it belongs in e2e.

What

Two tests against a spawned daemon:

a_definition_written_by_hand_starts_and_stops_serving — a definition appears in the config directory with no IPC call and no restart, and starts serving; editing it to paused = true releases the port; resuming brings it back. Pausing is worth pinning specifically: before #1119 it did nothing at all, leaving the listener bound and answering.

a_definition_that_does_not_parse_leaves_the_service_running — a file that cannot be parsed leaves the running service untouched (the operator's mistake costs them the edit, not the service), and a corrected file is picked up on a later pass, so a bad save is not a state the daemon must be restarted out of.

Keeping it honest in CI

  • No harness credential needed. Neither test lets a request reach a session — an unauthenticated request returning 401 proves the endpoint is up and is this service, without a model. A CI runner has no smith credential, so anything else would be flaky by construction.
  • Polled, not slept. Waits run against a 30s deadline rather than sleeping the watcher's interval, which is an implementation detail.
  • Guards itself. The first assertion is that the port is not serving before the definition exists — a port that happened to be busy would otherwise make every later assertion meaningless.

Verification

Disabling the watcher fails both tests, so they genuinely exercise the path rather than passing incidentally:

with watcher:     2 passed          (~10s)
watcher disabled: 0 passed; 2 failed

3/3 clean runs after restoring. Production code untouched — this PR adds one test file.

The config directory is a documented, hand-editable surface, but the only
coverage for an edit made there was manual: a definition file has no IPC
call to assert against, and the sole evidence it applied is that the
daemon's listeners changed. That needs a real daemon and a real socket.

Two tests against a spawned daemon: a definition written into the config
directory starts serving, pausing it releases the port, and resuming
brings it back; and a file that does not parse leaves the running service
untouched until a corrected one is saved.

Neither lets a request reach a session, so neither needs a harness
credential a CI runner does not have — an unauthenticated request is
enough to prove the endpoint is up and is this service. Waits are polled
against generous deadlines rather than slept, since the watcher's interval
is an implementation detail.

Verified by disabling the watcher: both tests fail.
@edwin-zvs
edwin-zvs merged commit ee7fb5a into main Aug 1, 2026
1 check passed
@edwin-zvs
edwin-zvs deleted the e2e-service-watcher branch August 1, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant