OverviewFilesCommitsIssuesDocsReleasesPeers

favela-peer / test / bridge-channel.test.js

55 lines · javascript ref:
// One RPC channel per connection — because a retry must not fail for a reason of its own making.
//
// ⛔ WHAT HAPPENED. `connectBridge` built a fresh ProtomuxRPC every call. Protomux keys a channel by
// protocol on a given stream, so the second attempt over an already-open connection opened a SECOND
// channel for the same protocol and failed with "duplicate channel". Observed by a person doing the
// most ordinary thing possible after an error: trying again.
//
// ⚠ The failure is worse than it sounds, because the message describes the plumbing rather than the
// act. Someone who mistyped a name is told about channels.

import test from 'brittle'
import { Duplex } from 'streamx'
import b4a from 'b4a'
import { connectBridge } from '../lib/bridge.js'

const KEY = 'a'.repeat(64)

// A swarm stub whose "connection" is already open to the key we ask for — the retry case.
function swarmWith (conn) {
  return { connections: new Set([conn]), join: () => ({ flushed: async () => {} }), on () {}, off () {} }
}

// ⚠ A REAL duplex. Protomux writes a channel-open frame the moment a channel is created, so a plain
// object stub fails inside protomux rather than exercising anything this file is about.
function fakeConn () {
  const s = new Duplex({ write (data, cb) { cb(null) } })
  s.remotePublicKey = b4a.from(KEY, 'hex')
  return s
}

test('★★ asking twice over one connection reuses the channel', async (t) => {
  const conn = fakeConn()
  const swarm = swarmWith(conn)

  const a = await connectBridge(swarm, KEY)
  const b = await connectBridge(swarm, KEY)

  t.is(a.rpc, b.rpc, 'the same channel — a second one is a "duplicate channel" error on retry')
})

test('⚠ a closed connection does not leave a dead channel behind', async (t) => {
  const conn = fakeConn()
  const swarm = swarmWith(conn)

  const a = await connectBridge(swarm, KEY)
  conn.emit('close')
  const b = await connectBridge(swarm, KEY)

  t.not(a.rpc, b.rpc, 'a reconnect gets a fresh channel rather than one on a dead stream')
})

test('⛔ a bad key is refused before any connection is attempted', async (t) => {
  await t.exception(() => connectBridge(swarmWith(fakeConn()), 'nonsense'), /64 hex/)
})