/**
* The sidecar must release overlay per-mux state when an overlay-swarm
* connection dies.
*
* OverlayProtocol keeps `_peers` (pruned by the channel's own onclose) and
* `_paired` (pruned ONLY by detach). The sidecar holds ONE _overlayProtocolV2
* for the whole daemon and attaches it to every inbound overlay connection, so
* an un-detached pairing pins the mux and its stream for the life of an
* always-on process.
*
* This is the third instance of one defect: hyper-deploy 0.4.11 fixed
* DeployServer._onConnection, 0.4.13 fixed the public
* DeployServer.serveOnConnection, and this is the attach site the sidecar owns
* directly (lib/index.js, overlay-swarm 'connection' handler).
*
* Drives the real OverlayProtocol over a real Protomux on a real SecretStream
* pair — a stubbed protocol here would only certify whatever the stub does.
*/
import test from 'brittle'
import SecretStream from '@hyperswarm/secret-stream'
import { OverlayProtocol } from 'hyper-overlay/protocol'
import { Sidecar } from '../lib/index.js'
function pair () {
const a = new SecretStream(true)
const b = new SecretStream(false)
a.rawStream.pipe(b.rawStream).pipe(a.rawStream)
return { a, b }
}
async function waitFor (fn, timeoutMs = 5000) {
const t0 = Date.now()
while (Date.now() - t0 < timeoutMs) {
if (fn()) return true
await new Promise((r) => setTimeout(r, 25))
}
return false
}
test('overlay pairings are released when the connection closes', async (t) => {
t.timeout(30000)
const proto = new OverlayProtocol(null, null)
// Only _attachOverlayConn is under test; it touches _overlayProtocolV2 alone.
const sidecar = { _overlayProtocolV2: proto }
const attach = Sidecar.prototype._attachOverlayConn.bind(sidecar)
const N = 5
const conns = []
for (let i = 0; i < N; i++) {
const p = pair()
conns.push(p)
t.ok(attach(p.a), 'attached connection ' + i)
}
t.is(proto._paired.size, N, 'one paired mux per live connection')
for (const p of conns) {
p.a.destroy()
p.b.destroy()
}
await waitFor(() => proto._paired.size === 0)
t.is(proto._paired.size, 0, 'paired muxes released on close — otherwise every overlay connection the sidecar ever accepted is pinned for the life of the daemon')
})