From bad47a84444506ac6e23f0f990b6b6b953be022f Mon Sep 17 00:00:00 2001 From: Dai Ha Date: Sun, 20 Sep 2026 17:40:47 +0700 Subject: [PATCH] fleetd CI: skip unreadableFileIsUnknown honestly when root ignores the read bit The test set the file's read bit off via setReadable(false), but on the Gitea CI runner (root inside the container) the OS ignores that bit and opens the file anyway, so the test asserted on a condition it never actually created (LeadContextGaugeTest.java:142 UNKNOWN vs OK, CI run 1887 job 3104, commit fa62e99 on main). Add Files.isReadable(file) after setReadable(false) and before the gauge runs, and assumeFalse on it: a skip means "could not set up the case", never "the behaviour is fine". Restores the read bit either way so @TempDir cleanup still works. --- .../java/dev/ltms/fleet/lead/LeadContextGaugeTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fleetd/src/test/java/dev/ltms/fleet/lead/LeadContextGaugeTest.java b/fleetd/src/test/java/dev/ltms/fleet/lead/LeadContextGaugeTest.java index 3eb41be..6d89a65 100644 --- a/fleetd/src/test/java/dev/ltms/fleet/lead/LeadContextGaugeTest.java +++ b/fleetd/src/test/java/dev/ltms/fleet/lead/LeadContextGaugeTest.java @@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicLong; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeFalse; /** * Ticket "lead context gauge" — fleetd could not see how full a lead's own Claude Code context @@ -137,6 +138,15 @@ class LeadContextGaugeTest { Path file = tmp.resolve("projects").resolve("some-project-slug").resolve(SESSION_ID + ".jsonl"); assertTrue(file.toFile().setReadable(false), "test setup: must be able to revoke read permission"); try { + // setReadable(false) really did clear the read bit (asserted above), but that alone + // does not prove the file is UNREADABLE: running as root (e.g. a CI container) ignores + // the read bit and opens the file anyway. Files.isReadable checks what actually happens + // on open, not the bit. When it still reports readable, this test cannot create the + // condition it needs on this machine, so it skips honestly instead of asserting on a + // state that was never reached. A skip here means "I could not set up the case", NOT + // "the UNKNOWN behaviour is fine" -- it is not evidence either way. + assumeFalse(Files.isReadable(file), + "runs as root (CI container): the read bit does not stop root, so this case cannot be set up here"); LeadContextGauge gauge = new LeadContextGauge(); LeadContextGauge.Reading reading = gauge.read(configDir, SESSION_ID, "claude"); assertEquals(LeadContextGauge.State.UNKNOWN, reading.state()); -- 2.52.0