/** * The recurrence gate for #539. * * The sim used to number its zones exactly like a real celilo fleet, so a * leaked stack on celilo's own forgejo-builder (which lives at 10.0.10.12 in * the REAL dmz) put a second interface on the builder's own /24 and blackholed * every containerized CI job's route to the forge. These tests make the two * properties that prevent it non-negotiable: * * 1. every simulated private zone lives inside SIM_PRIVATE_SUPERNET, and * 2. the retired fleet-colliding prefixes appear NOWHERE in the suite. * * (2) is the one that matters in practice: the plan itself is one table, but * shell scripts, Knot zones and dnsmasq configs can't import TypeScript and so * hard-code the values. This is what catches "I changed it in one place". */ import { describe, expect, test } from 'bun:test'; import { execSync } from 'node:child_process'; import { subnetContains } from '@celilo/capabilities'; import { SIM_PRIVATE_SUPERNET, ZONE_GATEWAYS, ZONE_SUBNETS, type Zone } from './types'; const REPO_ROOT = execSync('git rev-parse --show-toplevel', { cwd: import.meta.dir, encoding: 'utf-8', }).trim(); /** * Prefixes the sim must never use again: the fleet's zone /24s and the * operator's LAN. Prefix match — `10.0.10.` catches an address, a CIDR and a * prose mention alike, which is what we want. */ const RETIRED_PREFIXES = ['10.0.10.', '10.0.20.', '10.0.30.', '10.0.120.', '192.168.']; /** * Match the plain form AND the regex-escaped form (`192\.168\.0\.10`). Two * escaped literals inside `toThrow(/…/)` survived the #539 sweep precisely * because a naive search for the plain text does not see them. */ function toPattern(prefix: string): string { return prefix.replace(/\./g, '\\\\?\\.'); } /** Everything that can put an address on a simulated network or assert one. */ const SCANNED_PATHS = ['packages/e2e', 'e2e/tests', 'modules/*/e2e']; /** * CHANGELOG is history — it describes what the addresses WERE. This test file * necessarily names the retired prefixes to ban them. */ const EXCLUDED = [/^packages\/e2e\/CHANGELOG\.md$/, /address-plan\.test\.ts$/]; /** * A single LINE may exempt itself with `#539-ok: `. * * There is one legitimate reason to write a banned prefix: enumerating an * RFC 1918 block as a CLASS, which any correct private-address predicate must * do. `192.168.` is both the operator's LAN (banned) and 192.168.0.0/16 * (unavoidable), and RETIRED_PREFIXES cannot tell them apart. The tell that * this is the prefix list's blind spot rather than a real judgement: `10.` sits * beside `192.168.` in exactly such a predicate and escapes only because `10.` * was never added to the list. * * Deliberately per-line and not per-file. Excluding a file would blind the gate * to every OTHER address in it, which is how a suppression becomes the next * leak. The reason is required — a marker with nothing after the colon does not * match, because an exemption that names only a line number is the next * reader's mystery. */ const INLINE_EXEMPTION = /#539-ok:\s*\S/; function grepRetired(): string[] { const pattern = RETIRED_PREFIXES.map(toPattern).join('|'); let out = ''; try { out = execSync(`git grep -nE '${pattern}' -- ${SCANNED_PATHS.join(' ')}`, { cwd: REPO_ROOT, encoding: 'utf-8', maxBuffer: 8 * 1024 * 1024, }); } catch { // git grep exits 1 when there are no matches — that is the passing case. return []; } return out .split('\n') .filter(Boolean) .filter((line) => !EXCLUDED.some((re) => re.test(line.split(':')[0] as string))) .filter((line) => !INLINE_EXEMPTION.test(line)); } describe('simulated address plan (#539)', () => { test('every zone lives inside the sim supernet', () => { for (const zone of Object.keys(ZONE_SUBNETS) as Zone[]) { const base = ZONE_SUBNETS[zone].split('/')[0]; expect(subnetContains(SIM_PRIVATE_SUPERNET, base)).toBe(true); expect(subnetContains(SIM_PRIVATE_SUPERNET, ZONE_GATEWAYS[zone])).toBe(true); expect(subnetContains(ZONE_SUBNETS[zone], ZONE_GATEWAYS[zone])).toBe(true); } }); test('zones do not overlap each other', () => { const subnets = Object.values(ZONE_SUBNETS); expect(new Set(subnets).size).toBe(subnets.length); }); test('the fleet-colliding prefixes appear nowhere in the suite', () => { const hits = grepRetired(); expect( hits, `The e2e suite must not use a real fleet's addresses (#539). Offending lines:\n${hits.join('\n')}\n\n` + `Use zoneIp()/ZONE_SUBNETS from packages/e2e/src/types.ts, or an address inside ${SIM_PRIVATE_SUPERNET}.`, ).toEqual([]); }); });