OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git-v3 / test / autobase-guards.test.js

75 lines · javascript ref:
// The two autobase patches this daemon cannot boot safely without.
//
// ⛔ THE HOLE THIS CLOSES. `scripts/patch-autobase-warmup.cjs` re-applies both on every npm install —
// proven against a pristine upstream copy — so a REINSTALL cannot revert them. An autobase BUMP can:
// the anchors move, the script prints "anchor not found … SKIPPING" and the install SUCCEEDS. Both
// guards vanish silently, and what they prevent is a SIGABRT crash-loop on boot and a daemon wedged
// in a microtask chain that accepts nothing.
//
// ⚠ A console line at install time is not a defence. Nobody reads install output, and the symptom
// arrives days later wearing a different face — which is how both of these were found the first time.

import test from 'brittle'
import { readFileSync } from '#node:fs'
import { join } from '#node:path'
import { checkAutobaseGuards, assertAutobaseGuards, GUARDS } from '../lib/autobase-guards.js'

const ROOT = new URL('..', import.meta.url).pathname

const patched = () => ({
  'node_modules/autobase/lib/apply-state.js': 'x\n// GUARD (pgv3 patch): …\ny',
  'node_modules/autobase/index.js': 'a\n// BOUND (pgv3 patch): …\nb'
})
const reader = (files) => (p) => (p in files ? files[p] : null)

test('both guards present — boots', (t) => {
  const r = checkAutobaseGuards({ read: reader(patched()) })
  t.ok(r.ok)
  t.is(r.missing.length, 0)
  t.is(r.unreadable.length, 0)
})

test('★★★ a guard positively ABSENT refuses the boot, and names what it protected', (t) => {
  const files = patched()
  files['node_modules/autobase/index.js'] = 'a\n// upstream, unpatched\nb'
  t.exception(
    () => assertAutobaseGuards({ read: reader(files), env: {}, log: () => {} }),
    /_appendBatch flush loop/,
    'the error says what breaks, not merely that a string is missing'
  )
})

test('⛔ a file we cannot READ does not refuse — unknown is not a fact', (t) => {
  const said = []
  // The layout could have changed, this could be a bundled tree, the check itself could be wrong.
  // Refusing to boot a production forge over our own uncertainty is worse than what we guard against.
  const r = assertAutobaseGuards({ read: () => null, env: {}, log: (m) => said.push(m) })
  t.ok(r.ok, 'unreadable is not missing')
  t.is(said.length, GUARDS.length, 'but every one it could not verify is said out loud')
  t.ok(said.every((m) => /NOT verifying/.test(m)))
})

test('⚠ the override boots, and says so', (t) => {
  const files = patched()
  delete files['node_modules/autobase/index.js']
  files['node_modules/autobase/index.js'] = 'unpatched'
  const said = []
  const r = assertAutobaseGuards({
    read: reader(files),
    env: { PEAR_GIT_ALLOW_UNPATCHED_AUTOBASE: '1' },
    log: (m) => said.push(m)
  })
  t.absent(r.ok)
  t.ok(r.overridden)
  t.ok(said.some((m) => /OVERRIDDEN/.test(m)), 'an override that is silent is indistinguishable from a check that does not run')
})

test('★ the real tree passes — this is the check that would have caught a bump', async (t) => {
  const r = checkAutobaseGuards({
    read: (p) => { try { return readFileSync(join(ROOT, p), 'utf8') } catch { return null } }
  })
  // ⚠ If autobase is ever unreadable here this goes to `unreadable` and passes — deliberately. The
  // assertion is about THIS tree being patched, not about the test environment having node_modules.
  t.is(r.missing.length, 0, 'no guard is positively missing in the installed autobase')
})