fleetd #602 gauge-wiring follow-up: pin Fleetd.main's LeadConfigDirSource wiring
Extract the inline new FleetMcp.LeadConfigDirSource(leadConfigDirLookup(...)) construction in Fleetd.main into a package-private factory, Fleetd.leadConfigDirSource, mirroring loopHealthSource/capacitySource/ healthCoverageSource. Add FleetdLeadConfigDirSourceWiringTest, which calls the factory directly with real Profile/Leader fixtures and asserts the returned source resolves a real configDir -- a property that is false if the factory's body is mutated to return LeadConfigDirSource.none(). Neither FleetMcpLeadContextGaugeWiringTest nor FleetdLeadConfigDirLookupTest could catch main losing this wiring: each builds its own instance instead of calling what main calls. This closes that gap at the factory level, matching the standard already accepted for loopHealthSource's own wiring test.
This commit is contained in:
@@ -673,9 +673,9 @@ public final class Fleetd {
|
|||||||
outageSource,
|
outageSource,
|
||||||
new FleetMcp.LeadSeatSource(leadSeatLookup(() -> config.get().profiles(), leaders, leads)),
|
new FleetMcp.LeadSeatSource(leadSeatLookup(() -> config.get().profiles(), leaders, leads)),
|
||||||
// fleetd #602 gauge-wiring: threads each lead's configured configDir into the
|
// fleetd #602 gauge-wiring: threads each lead's configured configDir into the
|
||||||
// context gauge — see leadConfigDirLookup's own doc for why this, not a hardcoded
|
// context gauge — see leadConfigDirSource's own doc for why this, not a hardcoded
|
||||||
// null, is what fleet_list's context row now reads.
|
// null, is what fleet_list's context row now reads.
|
||||||
new FleetMcp.LeadConfigDirSource(leadConfigDirLookup(() -> config.get().profiles(), leaders)),
|
leadConfigDirSource(() -> config.get().profiles(), leaders),
|
||||||
// fleetd #361: the operator-declared peers this daemon's fleet_list should try to
|
// fleetd #361: the operator-declared peers this daemon's fleet_list should try to
|
||||||
// reach. Read from the SAME snapshot leadMailbox itself opened from (cfg.coordinator()),
|
// reach. Read from the SAME snapshot leadMailbox itself opened from (cfg.coordinator()),
|
||||||
// not the live config.get() — coordinator wiring is already boot-time-fixed (see
|
// not the live config.get() — coordinator wiring is already boot-time-fixed (see
|
||||||
@@ -1611,6 +1611,27 @@ public final class Fleetd {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fleetd #602 gauge-wiring follow-up (PR #606 review comment 17353): {@code main} used to build
|
||||||
|
* {@code new FleetMcp.LeadConfigDirSource(leadConfigDirLookup(...))} inline, with nothing a test
|
||||||
|
* could call directly. Measured on that shape: replacing the whole expression with {@code
|
||||||
|
* FleetMcp.LeadConfigDirSource.none()} at the call site compiled with 0 errors and left the full
|
||||||
|
* 1822-test suite green — the daemon could be changed to always report every lead's context as
|
||||||
|
* {@code UNKNOWN}, forever, while every test stayed green. That is the same hand-built-vs-wired
|
||||||
|
* shape as fleetd #561/#248/#426/#562 ({@link #loopHealthSource}).
|
||||||
|
*
|
||||||
|
* <p>The fix extracts the inline {@code new} into this factory, in the same style as {@link
|
||||||
|
* #loopHealthSource}/{@link #capacitySource}/{@link #healthCoverageSource} — which is exactly
|
||||||
|
* what makes it directly callable from {@code FleetdLeadConfigDirSourceWiringTest}. That test
|
||||||
|
* calls this factory with real {@link FleetConfig.Profile}/{@link FleetConfig.Leader} fixtures and
|
||||||
|
* asserts the returned source resolves a real {@code configDir} — a property that would be false
|
||||||
|
* if this method's body were mutated to {@code return FleetMcp.LeadConfigDirSource.none();}.
|
||||||
|
*/
|
||||||
|
static FleetMcp.LeadConfigDirSource leadConfigDirSource(Supplier<Map<String, FleetConfig.Profile>> profiles,
|
||||||
|
Map<String, FleetConfig.Leader> leaders) {
|
||||||
|
return new FleetMcp.LeadConfigDirSource(leadConfigDirLookup(profiles, leaders));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fleetd #248 / fleetd#201 Unit 5: package-private factory for the per-target backend-error
|
* fleetd #248 / fleetd#201 Unit 5: package-private factory for the per-target backend-error
|
||||||
* pattern lookup {@link CompletionResolver} classifies a pane scrape against. Closes over the
|
* pattern lookup {@link CompletionResolver} classifies a pane scrape against. Closes over the
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package dev.ltms.fleet;
|
||||||
|
|
||||||
|
import dev.ltms.fleet.config.FleetConfig;
|
||||||
|
import dev.ltms.fleet.mcp.FleetMcp;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fleetd #602 gauge-wiring follow-up (PR #606 review comment 17353): {@code Fleetd.main}'s {@code
|
||||||
|
* LeadConfigDirSource} local used to be a bare {@code new FleetMcp.LeadConfigDirSource(
|
||||||
|
* leadConfigDirLookup(...))} built inline, with nothing a test could call directly. Measured on
|
||||||
|
* that shape: replacing the whole expression with {@code FleetMcp.LeadConfigDirSource.none()} at
|
||||||
|
* the call site compiled with 0 errors and left the full 1822-test suite green — the daemon could
|
||||||
|
* be changed to always report every lead's context as {@code UNKNOWN}, forever, and no test would
|
||||||
|
* notice. That is the same hand-built-vs-config-wired shape as fleetd #561/#248/#426/#562
|
||||||
|
* ({@code FleetdLoopHealthSourceWiringTest}).
|
||||||
|
*
|
||||||
|
* <p>{@code FleetMcpLeadContextGaugeWiringTest} and {@code FleetdLeadConfigDirLookupTest} both
|
||||||
|
* predate this class and are both still correct — but neither can catch the mutation above. One
|
||||||
|
* builds its own {@code FleetMcp} and hands it its own {@code LeadConfigDirSource}; the other
|
||||||
|
* builds its own lookup and calls {@link Fleetd#leadConfigDirLookup} directly. Neither one ever
|
||||||
|
* calls the thing {@code Fleetd.main} actually calls.
|
||||||
|
*
|
||||||
|
* <p>The fix extracts the inline {@code new} into {@link Fleetd#leadConfigDirSource}, a
|
||||||
|
* package-private factory in the same style as {@link Fleetd#loopHealthSource}/{@link
|
||||||
|
* Fleetd#capacitySource}/{@link Fleetd#healthCoverageSource} — which is exactly what makes it
|
||||||
|
* directly callable here. This test calls that factory with real {@link FleetConfig.Profile}/
|
||||||
|
* {@link FleetConfig.Leader} fixtures (the same shapes {@code FleetdLeadConfigDirLookupTest}
|
||||||
|
* already uses) and asserts the returned source resolves a real {@code configDir} — a property
|
||||||
|
* that would be false if {@link Fleetd#leadConfigDirSource} were mutated to {@code return
|
||||||
|
* FleetMcp.LeadConfigDirSource.none();}. Measured: mutating exactly that line makes
|
||||||
|
* {@link #resolvesTheRealConfiguredConfigDir()} fail ({@code expected: </mnt/opus-claude> but was:
|
||||||
|
* <null>}); restoring it makes the whole suite green again.
|
||||||
|
*
|
||||||
|
* <p><b>What this class does not and cannot cover.</b> {@code main}'s own line —
|
||||||
|
* {@code leadConfigDirSource(() -> config.get().profiles(), leaders)} — could itself be swapped
|
||||||
|
* for a bare {@code FleetMcp.LeadConfigDirSource.none()}, bypassing this factory entirely. Measured:
|
||||||
|
* that exact mutation compiles with 0 errors and leaves every test in this file, and the full
|
||||||
|
* 1825-test suite, green. {@link Fleetd#loopHealthSource}'s own wiring test has the identical gap
|
||||||
|
* for its own one-line call in {@code main} — no test in this codebase calls {@code Fleetd.main}
|
||||||
|
* far enough to observe which factory call it made. This class narrows the gap from "nothing tests
|
||||||
|
* the wiring" (the pre-extraction state this ticket found) to "the factory's own logic is pinned,
|
||||||
|
* and main's call to it is a one-line, visually-verifiable delegation" — the same standard already
|
||||||
|
* accepted for {@code loopHealthSource}/{@code capacitySource}/{@code healthCoverageSource}.
|
||||||
|
*/
|
||||||
|
class FleetdLeadConfigDirSourceWiringTest {
|
||||||
|
|
||||||
|
private static FleetConfig.Profile profileWithConfigDir(String name, String configDir) {
|
||||||
|
return new FleetConfig.Profile(name, null, "claude-sonnet-5", configDir, null, null,
|
||||||
|
"tab", "fleet", "w #{n}", null, null, null, null, null, null, null,
|
||||||
|
null, 3, true, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FleetConfig.Leader leadOnProfile(String profile) {
|
||||||
|
return new FleetConfig.Leader(profile, "lead: primary", 1, "lead:", 10, "claude", "claude-sonnet-5");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("the returned source resolves the lead's REAL configured configDir, not a hardcoded null")
|
||||||
|
void resolvesTheRealConfiguredConfigDir() {
|
||||||
|
Map<String, FleetConfig.Profile> profiles = Map.of("opus", profileWithConfigDir("opus", "/mnt/opus-claude"));
|
||||||
|
Map<String, FleetConfig.Leader> leaders = Map.of("primary", leadOnProfile("opus"));
|
||||||
|
|
||||||
|
FleetMcp.LeadConfigDirSource source = Fleetd.leadConfigDirSource(() -> profiles, leaders);
|
||||||
|
|
||||||
|
assertEquals("/mnt/opus-claude", source.configDirFor().apply("primary"),
|
||||||
|
"the configDirFor function must delegate to the real leadConfigDirLookup — mutating "
|
||||||
|
+ "Fleetd.leadConfigDirSource's own body to `return FleetMcp.LeadConfigDirSource.none();` "
|
||||||
|
+ "must fail this assertion (measured: it does — see this test's class javadoc for the "
|
||||||
|
+ "companion measurement on main's one-line call to this factory, which this assertion "
|
||||||
|
+ "does not and structurally cannot cover)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("a lead on a profile with no configDir override still resolves to null, not a crash")
|
||||||
|
void leadWithNoConfigDirOverrideResolvesToNull() {
|
||||||
|
Map<String, FleetConfig.Profile> profiles = Map.of("opus", profileWithConfigDir("opus", null));
|
||||||
|
Map<String, FleetConfig.Leader> leaders = Map.of("primary", leadOnProfile("opus"));
|
||||||
|
|
||||||
|
FleetMcp.LeadConfigDirSource source = Fleetd.leadConfigDirSource(() -> profiles, leaders);
|
||||||
|
|
||||||
|
assertNull(source.configDirFor().apply("primary"),
|
||||||
|
"no configDir: override configured ⇒ null, so LeadContextGauge falls back to its own default");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("an unrecognised lead name resolves to null, not a thrown exception")
|
||||||
|
void unrecognisedLeadNameResolvesToNull() {
|
||||||
|
FleetMcp.LeadConfigDirSource source = Fleetd.leadConfigDirSource(Map::of, Map.of());
|
||||||
|
|
||||||
|
assertNull(source.configDirFor().apply("ghost-lead"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user