diff --git a/bridged/src/test/java/dev/ltms/bridged/herdr/FakeHerdr.java b/bridged/src/test/java/dev/ltms/bridged/herdr/FakeHerdr.java index 2ec0c5a..3da81cb 100644 --- a/bridged/src/test/java/dev/ltms/bridged/herdr/FakeHerdr.java +++ b/bridged/src/test/java/dev/ltms/bridged/herdr/FakeHerdr.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; /** * Recording fake {@link HerdrClient} for unit/acceptance tests. Returns canned frames @@ -22,7 +23,13 @@ public final class FakeHerdr implements HerdrClient { public static final long WORKER_PID = 4242; private final ObjectMapper mapper = new ObjectMapper(); - public final List calls = new ArrayList<>(); + /** + * Thread-safe on purpose. Background loops — {@link dev.ltms.bridged.msg.ReplyPushLoop} and the + * lead heartbeat — call this fake from their own scheduler threads while a test polls + * {@link #called} from the test thread. A plain {@code ArrayList} threw + * {@code ConcurrentModificationException} out of {@code called()} when a nudge landed mid-stream. + */ + public final List calls = new CopyOnWriteArrayList<>(); private boolean healthy = true; private final List extraWorkspaces = new ArrayList<>(); private final List extraAgents = new ArrayList<>();