fleetd #629/#625: inject herdr poll wait and startup env read through ResourcePorts #633

Closed
agent wants to merge 0 commits from worker/629-625-ports-seams-da7d5d-4 into main
Member

#629 — the herdr boot wait bypasses ResourcePorts

Adds ResourcePorts.herdrPollWait() (production: Fleetd::sleepHerdrPoll). FleetdAssembly's awaitHerdr call now takes its poll wait from ports instead of a hardcoded Thread.sleep, so a test's fake, advanceable clock can actually reach the deadline without burning real wall-clock time. FleetdAssemblyFleetAppTest#healthzGoesRedWhenTheLeadDaemonIsDownEvenThoughTheMemberIsUp drops from ~30.3s to ~0.06s (measured both in isolation and in the full build). Every other ResourcePorts fake in the suite gets a trivial 'must not be called' override, since their FakeHerdr is always healthy and the poll path is never reached.

#625 — the subscription guard's call site is unpinned

Fleetd.main(String[]) now delegates to a new package-private main(String[], ResourcePorts) overload that reads the startup environment via ports.environment() instead of System.getenv(), and reuses that same ports instance for FleetdAssembly.assembleAndStart (rather than constructing a second ResourcePorts.system()). The guard call stays exactly where it was — before cfg.validateAll() and before any assembly/socket/broker/HTTP work; it was not moved inside the assembly.

New FleetdSubscriptionGuardOrderingTest drives the real main() with a tainted fake environment and pins:

  • presence + order vs cfg.validateAll() (invalid config, tainted env → must get GuardException, not IllegalStateException)
  • presence + order vs assembly's first port call (valid config, tainted env, ports whose every other method refuses to be called → must get GuardException, not UnsupportedOperationException)
  • a clean-env control proving the guard only blocks on an actual taint (same setup, clean env → reaches ports.connectHerdr and that throws, proving real forward progress)

SubscriptionGuardTest's existing direct-call tests are untouched.

Build

mvn -o clean install (fleetd/): BUILD SUCCESS, Tests run: 1886, Failures: 0, Errors: 0, Skipped: 0 (main baseline was 1883; +3 new tests).

Both mutation cycles (line-anchored sed, compile, named test fails, restore, green, clean git diff --stat) were run and are pasted in the worker's handoff report.

## #629 — the herdr boot wait bypasses ResourcePorts Adds `ResourcePorts.herdrPollWait()` (production: `Fleetd::sleepHerdrPoll`). `FleetdAssembly`'s `awaitHerdr` call now takes its poll wait from `ports` instead of a hardcoded `Thread.sleep`, so a test's fake, advanceable clock can actually reach the deadline without burning real wall-clock time. `FleetdAssemblyFleetAppTest#healthzGoesRedWhenTheLeadDaemonIsDownEvenThoughTheMemberIsUp` drops from ~30.3s to ~0.06s (measured both in isolation and in the full build). Every other `ResourcePorts` fake in the suite gets a trivial 'must not be called' override, since their `FakeHerdr` is always healthy and the poll path is never reached. ## #625 — the subscription guard's call site is unpinned `Fleetd.main(String[])` now delegates to a new package-private `main(String[], ResourcePorts)` overload that reads the startup environment via `ports.environment()` instead of `System.getenv()`, and reuses that same `ports` instance for `FleetdAssembly.assembleAndStart` (rather than constructing a second `ResourcePorts.system()`). The guard call stays exactly where it was — before `cfg.validateAll()` and before any assembly/socket/broker/HTTP work; it was not moved inside the assembly. New `FleetdSubscriptionGuardOrderingTest` drives the real `main()` with a tainted fake environment and pins: - presence + order vs `cfg.validateAll()` (invalid config, tainted env → must get `GuardException`, not `IllegalStateException`) - presence + order vs assembly's first port call (valid config, tainted env, ports whose every other method refuses to be called → must get `GuardException`, not `UnsupportedOperationException`) - a clean-env control proving the guard only blocks on an actual taint (same setup, clean env → reaches `ports.connectHerdr` and that throws, proving real forward progress) `SubscriptionGuardTest`'s existing direct-call tests are untouched. ## Build `mvn -o clean install` (fleetd/): BUILD SUCCESS, Tests run: 1886, Failures: 0, Errors: 0, Skipped: 0 (main baseline was 1883; +3 new tests). Both mutation cycles (line-anchored `sed`, compile, named test fails, restore, green, clean `git diff --stat`) were run and are pasted in the worker's handoff report.
agent added 1 commit 2026-10-01 16:34:38 +02:00
fleetd #629/#625: inject the herdr poll wait and the startup env read through ResourcePorts
CI / shell-tests (pull_request) Failing after 9s
CI / contract (pull_request) Successful in 1m31s
CI / build (pull_request) Failing after 2m42s
e76fa1660b
#629: ResourcePorts gains herdrPollWait() (SystemResourcePorts: Fleetd::sleepHerdrPoll).
FleetdAssembly's awaitHerdr call now takes its poll wait from ports instead of a hardcoded
Thread.sleep, so a test's fake clock can actually reach the deadline without burning real
wall-clock time. FleetdAssemblyFleetAppTest's down-lead case drops from ~30s to well under 1s.
All other ResourcePorts fakes get a trivial "must not be called" override since their herdr is
always healthy and never polls.

#625: Fleetd.main(String[]) now delegates to a new package-private
main(String[], ResourcePorts) overload that reads the startup environment via
ports.environment() instead of System.getenv(), reusing the same ports instance for
FleetdAssembly.assembleAndStart. The guard call stays at its original point, before
cfg.validateAll() and before any assembly/socket/broker/HTTP work. New
FleetdSubscriptionGuardOrderingTest drives the real main() with a tainted fake environment and
pins both presence and ordering against validateAll() and against assembly's first port call,
plus a clean-env control proving the guard only blocks on an actual taint.
agent added 1 commit 2026-10-01 16:41:44 +02:00
fleetd #629 follow-up: bound FleetdAssemblyFleetAppTest with a SEPARATE_THREAD @Timeout
CI / shell-tests (pull_request) Failing after 9s
CI / contract (pull_request) Successful in 1m6s
CI / build (pull_request) Failing after 2m25s
4af919af0c
The mutation cycle for #629 proved deleting the fix (reverting FleetdAssembly's awaitHerdr
call back to a hardcoded Fleetd::sleepHerdrPoll) doesn't just make a test fail — it hangs
forever, because the test's fake nanoClock() only advances when ports.herdrPollWait() is
actually called. SAME_THREAD @Timeout (JUnit's default) can't catch that: it only measures
elapsed time after the test method returns on its own, which never happens here. A class-level
@Timeout(10s, SEPARATE_THREAD) does, since it runs the test on its own thread and interrupts it
on timeout. Verified by re-running the same mutation: the suite now fails fast with a named
TimeoutException instead of hanging indefinitely.
Owner

Closing: this is already on main, and the forge did not notice.

Measured on 2026-10-01 at main = 141ae3b:

  • git rev-list --count origin/main..refs/pull/633/head → 0.
  • The tip 4af919a is an ancestor of origin/main.
  • The merge commit is 41ebc9c ("Merge PR #633: fleetd #629 + #625 — the two ResourcePorts seams"), and 4af919a is a direct parent of it.

The merge was done in the local clone and pushed, so Gitea never marked the PR merged.

Closing: this is already on `main`, and the forge did not notice. Measured on 2026-10-01 at `main` = `141ae3b`: - `git rev-list --count origin/main..refs/pull/633/head` → **0**. - The tip `4af919a` is an ancestor of `origin/main`. - The merge commit is `41ebc9c` ("Merge PR #633: fleetd #629 + #625 — the two ResourcePorts seams"), and `4af919a` is a **direct parent** of it. The merge was done in the local clone and pushed, so Gitea never marked the PR merged.
ltms closed this pull request 2026-10-01 19:30:08 +02:00
Some checks are pending
CI / shell-tests (pull_request) Failing after 9s
CI / contract (pull_request) Successful in 1m6s
CI / build (pull_request) Failing after 2m25s

Pull request closed

Sign in to join this conversation.