OverviewFilesCommitsIssuesDocsReleasesPeers

pgh / test / app-boot-port-conflict.test.js

42 lines · javascript ref:
// Unit test for portConflictSkips — the boot-time guard that stops two same-port apps from both
// being started (the second only crash-loops on EADDRINUSE). Root cause of the tabertron
// atproto-pds/atproto-bridge :3399 clash (a stale duplicate install, both autostart).
import test from 'brittle'
import { portConflictSkips } from '../lib/dep-graph.js'

test('portConflictSkips: later same-port app is skipped, earlier owns the port', (t) => {
  const ports = { 'atproto-bridge': 3399, 'atproto-pds': 3399 }
  const skips = portConflictSkips(['atproto-bridge', 'atproto-pds'], (n) => ports[n] ?? null)
  t.absent(skips.has('atproto-bridge'), 'first app (owner) is not skipped')
  t.ok(skips.has('atproto-pds'), 'second same-port app is skipped')
  t.is(skips.get('atproto-pds'), 'port 3399 already claimed by atproto-bridge', 'legible reason names the owner')
})

test('portConflictSkips: topo-order decides the owner (reverse the order)', (t) => {
  const ports = { 'atproto-bridge': 3399, 'atproto-pds': 3399 }
  const skips = portConflictSkips(['atproto-pds', 'atproto-bridge'], (n) => ports[n] ?? null)
  t.ok(skips.has('atproto-bridge'), 'now the later one is skipped')
  t.is(skips.get('atproto-bridge'), 'port 3399 already claimed by atproto-pds')
})

test('portConflictSkips: distinct ports never conflict', (t) => {
  const ports = { a: 5005, b: 3399, c: 4040 }
  const skips = portConflictSkips(['a', 'b', 'c'], (n) => ports[n])
  t.is(skips.size, 0, 'no skips when every port is unique')
})

test('portConflictSkips: apps with no declared port are ignored and never block', (t) => {
  const ports = { pgh: null, sidecar: null, bridge: 3399, pds: 3399 }
  const skips = portConflictSkips(['pgh', 'sidecar', 'bridge', 'pds'], (n) => ports[n])
  t.is(skips.size, 1, 'only the real conflict is flagged')
  t.ok(skips.has('pds'), 'the second :3399 app is the one skipped')
  t.absent(skips.has('pgh'), 'a portless app is never skipped')
})

test('portConflictSkips: three apps, two share a port', (t) => {
  const ports = { x: 8080, y: 8080, z: 8080 }
  const skips = portConflictSkips(['x', 'y', 'z'], (n) => ports[n])
  t.absent(skips.has('x'), 'first owns 8080')
  t.ok(skips.has('y') && skips.has('z'), 'both later apps skipped')
})