OverviewFilesCommitsIssuesDocsReleasesPeers

pgh / test / bootstrap-artifacts.test.js

322 lines · javascript ref:
import test from 'brittle'
import { mkdtempSync, writeFileSync, mkdirSync, readFileSync, existsSync, lstatSync, rmSync } from '#node:fs'
import { join } from '#node:path'
import { tmpdir } from '#node:os'

import { reconcileBootstrapArtifacts, bootstrapDir, hostLabel } from '../lib/bootstrap-artifacts.js'

// #66: <store>/bootstrap is produced by TARRING the local app trees flagged
// pgh.bootstrap. Event-driven (called from the install/OTA path), idempotent,
// no polling loop. install.sh is a symlink into the pgh tree.

// Minimal fake store: just the fields reconcileBootstrapArtifacts touches.
function fakeStore (root) {
  return { root, appsDir: join(root, 'apps'), init () { mkdirSync(this.appsDir, { recursive: true }) } }
}

function mkAppTree (appsDir, name, { bootstrap = true, label = 'linux-x64', treeHash, installSh = false } = {}) {
  const dir = join(appsDir, name)
  mkdirSync(join(dir, 'bin'), { recursive: true })
  const pkg = { name, version: '1.0.0' }
  if (bootstrap) { pkg.pgh = { bootstrap: true }; pkg.pghBootstrap = { label } }
  writeFileSync(join(dir, 'package.json'), JSON.stringify(pkg))
  if (treeHash) writeFileSync(join(dir, '.pgh-install.json'), JSON.stringify({ name, treeHash }))
  if (installSh) {
    mkdirSync(join(dir, 'scripts'), { recursive: true })
    writeFileSync(join(dir, 'scripts', 'install.sh'), '#!/bin/sh\necho hi\n')
  }
  return dir
}

function fakeTar (calls) {
  return (srcDir, destTar) => { calls.push({ srcDir, destTar }); writeFileSync(destTar, 'TAR:' + srcDir) }
}

test('reconcileBootstrapArtifacts tars bootstrap apps, symlinks install.sh, skips non-bootstrap', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-'))
  const store = fakeStore(root)
  store.init()
  mkAppTree(store.appsDir, 'pgh', { treeHash: 'aaa', installSh: true })
  mkAppTree(store.appsDir, 'pgh-sidecar', { treeHash: 'bbb' })
  mkAppTree(store.appsDir, 'hyper-tps', { bootstrap: false, treeHash: 'ccc' })

  const calls = []
  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar(calls), log: () => {}, serveAllArches: true })

  const dir = bootstrapDir(store)
  t.is(res.tarred.length, 2, 'tarred the 2 bootstrap apps')
  t.ok(existsSync(join(dir, 'pgh-bootstrap-bare-linux-x64.tar.gz')), 'pgh tarball present')
  t.ok(existsSync(join(dir, 'pgh-sidecar-bootstrap-bare-linux-x64.tar.gz')), 'sidecar tarball present')
  t.absent(existsSync(join(dir, 'hyper-tps-bootstrap-bare-linux-x64.tar.gz')), 'non-bootstrap app skipped')
  t.ok(res.installSh, 'install.sh reconciled')
  t.ok(lstatSync(join(dir, 'install.sh')).isSymbolicLink(), 'install.sh is a symlink')
  t.is(readFileSync(join(dir, 'install.sh'), 'utf8'), '#!/bin/sh\necho hi\n', 'install.sh resolves to the pgh tree')
})

test('reconcileBootstrapArtifacts regenerates a tarball only when the treeHash changes', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-c-'))
  const store = fakeStore(root); store.init()
  mkAppTree(store.appsDir, 'pgh', { treeHash: 'h1', installSh: true })
  const calls = []
  const tar = fakeTar(calls)

  await reconcileBootstrapArtifacts(store, { tarTree: tar })
  t.is(calls.length, 1, 'tarred once')
  await reconcileBootstrapArtifacts(store, { tarTree: tar })
  t.is(calls.length, 1, 'unchanged treeHash → cache hit, no re-tar')

  writeFileSync(join(store.appsDir, 'pgh', '.pgh-install.json'), JSON.stringify({ name: 'pgh', treeHash: 'h2' }))
  await reconcileBootstrapArtifacts(store, { tarTree: tar })
  t.is(calls.length, 2, 'changed treeHash → re-tar')
})

test('reconcileBootstrapArtifacts prunes a stale tarball when its app disappears', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-p-'))
  const store = fakeStore(root); store.init()
  mkAppTree(store.appsDir, 'pgh', { treeHash: 'h1', installSh: true })
  mkAppTree(store.appsDir, 'pgh-sidecar', { treeHash: 'h2' })
  const dir = bootstrapDir(store)

  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]) })
  t.ok(existsSync(join(dir, 'pgh-sidecar-bootstrap-bare-linux-x64.tar.gz')), 'sidecar tarball present')

  rmSync(join(store.appsDir, 'pgh-sidecar'), { recursive: true, force: true })
  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]) })
  t.ok(res.pruned.includes('pgh-sidecar-bootstrap-bare-linux-x64.tar.gz'), 'stale tarball pruned')
  t.absent(existsSync(join(dir, 'pgh-sidecar-bootstrap-bare-linux-x64.tar.gz')), 'stale tarball gone')
  t.ok(existsSync(join(dir, 'pgh-bootstrap-bare-linux-x64.tar.gz')), 'live tarball kept')
})

test('reconcileBootstrapArtifacts is a safe no-op with no bootstrap apps', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-e-'))
  const store = fakeStore(root); store.init()
  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]) })
  t.is(res.tarred.length, 0, 'nothing tarred')
  t.is(res.pruned.length, 0, 'nothing pruned')
  t.absent(res.installSh, 'no install.sh')
})

test('reconcileBootstrapArtifacts skips atomic-swap temp dirs (<app>.new-<ts>)', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-swap-'))
  const store = fakeStore(root); store.init()
  mkAppTree(store.appsDir, 'pgh-sidecar', { treeHash: 'h1' })
  // leftover interrupted swap — same package.json, not a live install
  mkAppTree(store.appsDir, 'pgh-sidecar.new-1780772775921', { treeHash: '' })

  const calls = []
  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar(calls) })
  t.is(res.tarred.length, 1, 'tarred only the real app, not the .new- temp')
  t.alike(res.tarred, ['pgh-sidecar-bootstrap-bare-linux-x64.tar.gz'], 'one clean tarball')
})

test('reconcileBootstrapArtifacts guards a malformed pghBootstrap.label (no double infix)', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-lbl-'))
  const store = fakeStore(root); store.init()
  // a tree whose label is corrupted (baked-in stage name)
  mkAppTree(store.appsDir, 'pgh-sidecar', { label: 'bootstrap-bare-linux-x64', treeHash: 'h1' })

  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })
  t.alike(res.tarred, ['pgh-sidecar-bootstrap-bare-linux-x64.tar.gz'], 'falls back to host label — no double infix')
})

test('reconcileBootstrapArtifacts names the tarball from the dir, not a corrupted pkg.name', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-nm-'))
  const store = fakeStore(root); store.init()
  // real-world tabertron case: an old build baked the stage name into pkg.name
  const dir = mkAppTree(store.appsDir, 'pgh-sidecar', { treeHash: 'h1' })
  const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'))
  pkg.name = 'pgh-sidecar-bootstrap-bare' // corrupted
  writeFileSync(join(dir, 'package.json'), JSON.stringify(pkg))

  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]) })
  t.alike(res.tarred, ['pgh-sidecar-bootstrap-bare-linux-x64.tar.gz'], 'tarball named from dir, no double infix')
})

test('default tarTree (real async spawn) produces a valid tarball without blocking', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-real-'))
  const store = fakeStore(root); store.init()
  const dir = mkAppTree(store.appsDir, 'pgh', { treeHash: 'h1', installSh: true })
  writeFileSync(join(dir, 'data.bin'), Buffer.alloc(64 * 1024, 7))

  // No tarTree injected → exercises the default async spawn path. An interval
  // proves the event loop keeps running while the tar child process works.
  let ticks = 0
  const iv = setInterval(() => { ticks++ }, 5)
  const res = await reconcileBootstrapArtifacts(store)
  clearInterval(iv)

  const tb = join(bootstrapDir(store), 'pgh-bootstrap-bare-linux-x64.tar.gz')
  t.alike(res.tarred, ['pgh-bootstrap-bare-linux-x64.tar.gz'], 'tarred via default spawn')
  t.ok(existsSync(tb), 'tarball exists')
  t.ok(lstatSync(tb).size > 0, 'tarball non-empty')
  t.ok(ticks > 0, 'event loop ran during tar (async, non-blocking)')
  rmSync(root, { recursive: true, force: true })
})

// Cross-arch: hostLabel() only ever names the LOCAL arch, so an all-x64 fleet
// can never tar linux-arm64 and /bootstrap 404s for arm64 VPSes. Bootstrap apps
// vendor prebuilt cross-arch tarballs under node_modules/<pkg>/dist/ — reconcile
// promotes those into the served dir.

// Drop a vendored cross-arch tarball into an app tree's node_modules/<pkg>/dist/.
function mkVendored (appDir, pkg, tarName, body = 'VENDORED') {
  const dist = join(appDir, 'node_modules', pkg, 'dist')
  mkdirSync(dist, { recursive: true })
  writeFileSync(join(dist, tarName), body)
  return join(dist, tarName)
}

test('reconcileBootstrapArtifacts promotes a vendored cross-arch tarball into the served dir', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-xarch-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  const src = mkVendored(appDir, 'pgh', 'pgh-bootstrap-bare-linux-arm64.tar.gz', 'ARM64BYTES')

  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })

  const dir = bootstrapDir(store)
  const arm = join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz')
  t.ok(existsSync(arm), 'arm64 tarball now served')
  t.is(readFileSync(arm, 'utf8'), 'ARM64BYTES', 'promoted the vendored bytes')
  t.ok(res.tarred.includes('pgh-bootstrap-bare-linux-arm64.tar.gz'), 'reported as produced')
  t.ok(existsSync(join(dir, 'pgh-bootstrap-bare-linux-x64.tar.gz')), 'host-arch tarball still tarred locally')
  // hardlink, not copy — same inode means serving arm64 costs no extra bytes
  t.is(lstatSync(arm).ino, lstatSync(src).ino, 'hardlinked to the vendored file (zero extra disk)')
})

test('a promoted cross-arch tarball survives the prune pass', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-xarch-p-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  mkVendored(appDir, 'pgh', 'pgh-bootstrap-bare-linux-arm64.tar.gz')

  const dir = bootstrapDir(store)
  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })
  t.ok(existsSync(join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz')), 'present after first reconcile')

  // Second pass is where a non-wanted artifact would get pruned.
  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })
  t.absent(res.pruned.includes('pgh-bootstrap-bare-linux-arm64.tar.gz'), 'not pruned')
  t.ok(existsSync(join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz')), 'still served after re-reconcile')
})

test('local tar wins for the host arch — a vendored same-label tarball never overwrites it', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-xarch-w-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  // a stale vendored tarball for OUR arch — must not shadow the fresh local tar
  mkVendored(appDir, 'pgh', 'pgh-bootstrap-bare-linux-x64.tar.gz', 'STALE')

  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })

  const hostTb = join(bootstrapDir(store), 'pgh-bootstrap-bare-linux-x64.tar.gz')
  t.not(readFileSync(hostTb, 'utf8'), 'STALE', 'host-arch tarball came from local tar, not the vendored copy')
})

// Measured on tabertron: pgh-sidecar-bootstrap-bare-linux-arm64.tar.gz lives ONLY
// in the pear-git-v3 tree, which is not a pgh.bootstrap app. install.sh fetches
// both pgh and pgh-sidecar under `set -e`, so missing the sidecar's arm64 tarball
// still breaks every arm64 install.
test('promotes a vendored tarball carried by a NON-bootstrap app tree', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-xarch-nb-'))
  const store = fakeStore(root); store.init()
  mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  // pear-git-v3 is NOT a bootstrap app, but it carries the sidecar's arm64 bytes
  const pgv3 = mkAppTree(store.appsDir, 'pear-git-v3', { bootstrap: false, treeHash: 'h2' })
  mkVendored(pgv3, 'pgh-sidecar', 'pgh-sidecar-bootstrap-bare-linux-arm64.tar.gz', 'SIDECAR-ARM64')

  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })

  const sc = join(bootstrapDir(store), 'pgh-sidecar-bootstrap-bare-linux-arm64.tar.gz')
  t.ok(existsSync(sc), 'sidecar arm64 tarball served despite carrier not being a bootstrap app')
  t.is(readFileSync(sc, 'utf8'), 'SIDECAR-ARM64', 'promoted the right bytes')
  t.ok(res.tarred.includes('pgh-sidecar-bootstrap-bare-linux-arm64.tar.gz'), 'reported as produced')
  t.absent(existsSync(join(bootstrapDir(store), 'pear-git-v3-bootstrap-bare-linux-x64.tar.gz')),
    'non-bootstrap carrier is still not tarred as a bootstrap app itself')
})

test('re-promotes when the vendored artifact is replaced underneath us', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-xarch-up-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  mkVendored(appDir, 'pgh', 'pgh-bootstrap-bare-linux-arm64.tar.gz', 'V1')

  const dir = bootstrapDir(store)
  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })
  t.is(readFileSync(join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz'), 'utf8'), 'V1', 'v1 served')

  // new upstream version replaces the vendored file (new inode)
  mkVendored(appDir, 'pgh', 'pgh-bootstrap-bare-linux-arm64.tar.gz', 'V2')
  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })
  t.is(readFileSync(join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz'), 'utf8'), 'V2', 're-promoted, not stale')
})

test('promotes from the app\'s OWN dist/, which is where these artifacts really live', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-owndist-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  // pgh/dist/ ships the cross-arch tarball alongside a .sha256 — no node_modules involved
  mkdirSync(join(appDir, 'dist'), { recursive: true })
  writeFileSync(join(appDir, 'dist', 'pgh-bootstrap-bare-linux-arm64.tar.gz'), 'OWN-DIST')
  writeFileSync(join(appDir, 'dist', 'pgh-bootstrap-bare-linux-arm64.tar.gz.sha256'), 'deadbeef')

  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })

  const dir = bootstrapDir(store)
  t.is(readFileSync(join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz'), 'utf8'), 'OWN-DIST', 'promoted from own dist/')
  t.absent(existsSync(join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz.sha256')), 'sidecar files not promoted')
})

test('own dist/ wins over a vendored copy of the same tarball', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-winner-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  mkdirSync(join(appDir, 'dist'), { recursive: true })
  writeFileSync(join(appDir, 'dist', 'pgh-bootstrap-bare-linux-arm64.tar.gz'), 'CANONICAL')
  mkVendored(appDir, 'somedep', 'pgh-bootstrap-bare-linux-arm64.tar.gz', 'STALE-VENDORED')

  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })

  const served = readFileSync(join(bootstrapDir(store), 'pgh-bootstrap-bare-linux-arm64.tar.gz'), 'utf8')
  t.is(served, 'CANONICAL', 'own dist/ took precedence, not the vendored copy')
})

test('hostLabel returns os-arch', (t) => {
  t.ok(/^[a-z0-9]+-[a-z0-9]+$/.test(hostLabel()), 'looks like <os>-<arch>')
})

// The opt-in itself. Promotion is a hardlink (no bytes), but SERVING a foreign
// arch is only useful on a machine that answers cold-start HTTPS /bootstrap
// fetches — a forge backend. Everyone else installs over hyper-deploy/overlay.
test('cross-arch promotion is OFF by default', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-optout-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  mkVendored(appDir, 'pgh', 'pgh-bootstrap-bare-linux-arm64.tar.gz', 'ARM64')

  // no serveAllArches
  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64' })

  const dir = bootstrapDir(store)
  t.absent(existsSync(join(dir, 'pgh-bootstrap-bare-linux-arm64.tar.gz')), 'arm64 NOT promoted without opt-in')
  t.ok(existsSync(join(dir, 'pgh-bootstrap-bare-linux-x64.tar.gz')), 'own arch still built')
  t.absent(res.tarred.includes('pgh-bootstrap-bare-linux-arm64.tar.gz'), 'not reported as produced')
})

test('opting in promotes, and opting back out prunes what it promoted', async (t) => {
  const root = mkdtempSync(join(tmpdir(), 'pgh-ba-toggle-'))
  const store = fakeStore(root); store.init()
  const appDir = mkAppTree(store.appsDir, 'pgh', { label: 'linux-x64', treeHash: 'h1', installSh: true })
  mkVendored(appDir, 'pgh', 'pgh-bootstrap-bare-linux-arm64.tar.gz', 'ARM64')
  const arm = join(bootstrapDir(store), 'pgh-bootstrap-bare-linux-arm64.tar.gz')

  await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64', serveAllArches: true })
  t.ok(existsSync(arm), 'promoted while opted in')

  // Turning it off must actually stop serving it — the prune pass drops any
  // tarball no longer in wantTarballs, which is what makes the toggle real.
  const res = await reconcileBootstrapArtifacts(store, { tarTree: fakeTar([]), label: 'linux-x64' })
  t.ok(res.pruned.includes('pgh-bootstrap-bare-linux-arm64.tar.gz'), 'pruned on opt-out')
  t.absent(existsSync(arm), 'no longer served')
})