FakeSeam

class FakeSeam(val selfId: PeerId = PeerId("self"), initialPeers: Set<PeerId> = setOf(selfId), initialState: SeamState = SeamState.Woven, policy: DeliveryPolicy = DeliveryPolicy.Reliable) : Seam

A test double for Seam with test-driver helpers for state mutation, frame delivery, and outgoing-frame inspection.

Defaults make FakeSeam() a ready-to-use, single-peer, SeamState.Woven seam in one line:

val seam = FakeSeam()
seam.deliver(PeerId("alice"), byteArrayOf(1, 2, 3))
val frame = seam.incoming.first()

For wired two-peer scenarios, prefer fakeSeamPair which cross-wires broadcast delivery between two seams.

Send semantics (matching the Seam contract):

The inbound buffer is bounded via policy (default DeliveryPolicy.Reliable). Unbounded delivery is structurally unrepresentable — pass a custom policy to change capacity or overflow behaviour.

initialPeers must contain selfId — in every state, as Seam.peers requires from construction onward. peers.value.size > 1 is the contract's sentinel for "at least one remote is connected", so a roster without selfId under-counts by one and a seam holding one remote reads as alone. Passing one throws IllegalArgumentException.

That obligation is an invariant, not a construction-time snapshot (#2546). Two doors used to reach the identical state the require refuses: removePeer applied to selfId now throws rather than holing the roster, and initialPeers is copied rather than retained, so a caller holding a MutableSet reference cannot edit the seam's roster out from under it after construction.

Constructing one already Torn is allowed, but only in the shape a real seam reaches: initialPeers must be setOf(selfId) (the default), because Seam.peers requires a torn seam's roster to be exactly that. Anything else throws IllegalArgumentException — see the init block. A seam constructed Torn also starts with incoming already completed, as tear leaves it.

Torn is terminal here too: weave refuses once torn rather than silently un-tearing, so a test cannot drive this fake through a transition no real seam performs. See weave for why that arm throws while tear is a silent no-op.

Constructors

Link copied to clipboard
constructor(selfId: PeerId = PeerId("self"), initialPeers: Set<PeerId> = setOf(selfId), initialState: SeamState = SeamState.Woven, policy: DeliveryPolicy = DeliveryPolicy.Reliable)

Properties

Link copied to clipboard

All payloads passed to broadcast, in call order. Each read returns a fresh defensive snapshot; two reads may observe different snapshots if a broadcast lands between them.

Link copied to clipboard
open val capability: StateFlow<TransportCapability>
Link copied to clipboard

All (peer, payload) pairs passed to sendTo, in call order. Each read returns a fresh defensive snapshot; two reads may observe different snapshots if a sendTo lands between them.

Link copied to clipboard
open override val incoming: Flow<Swatch>
Link copied to clipboard
open val maxPayloadBytes: Int?
Link copied to clipboard
open override val peers: StateFlow<Set<PeerId>>
Link copied to clipboard
open val plies: StateFlow<Map<PlyId, SeamState>>
Link copied to clipboard
open override val selfId: PeerId
Link copied to clipboard
open override val state: StateFlow<SeamState>

Functions

Link copied to clipboard
fun addPeer(peer: PeerId)

Add peer to the live peers set.

Link copied to clipboard
open suspend override fun broadcast(payload: ByteArray)
Link copied to clipboard
open suspend override fun close(reason: CloseReason)
Link copied to clipboard
suspend fun deliver(swatch: Swatch)

Push swatch directly into incoming, applying the configured DeliveryPolicy.

suspend fun deliver(from: PeerId, payload: ByteArray)

Push a frame from from into incoming, stamping sender and a monotonically increasing sequence (receiver-local, starting at 1).

Link copied to clipboard
fun removePeer(peer: PeerId)

Remove peer from the live peers set, leaving state untouched — the membership drain a real peer-mesh performs when one link dies while others survive.

Link copied to clipboard
open suspend override fun sendTo(peer: PeerId, payload: ByteArray)
Link copied to clipboard
fun tear(reason: CloseReason = CloseReason.Normal)

Transition state to SeamState.Torn with reason, collapsing peers to { selfId } and completing incoming. Idempotent.

Link copied to clipboard
fun weave()

Transition state from SeamState.Weaving to SeamState.Woven. Re-asserting SeamState.Woven on an already-woven seam is a harmless no-op.