chadtmiller.com/knotless

Git hosted in your atproto account, on any stock PDS, fast enough for agents.

git clone knotless://chadtmiller.com/knotless

needs the knotless git helper. set it up

main
141 lines · 5.9 KB Raw History
// Coverage over the stock reference PDS and the spaces alpha together,
// failing under 100% of lines or functions: what `just cov` runs.
//
//   node harness/cov.mjs <spaces dev-env> <ignore regex>
//
// The tests are built once, instrumented, and each test binary is run
// against both PDSes, several at a time, rather than one after another
// as `cargo test` would: one harness for each PDS, shared by every binary
// run against it, as `just pds` is. COV_JOBS sets how many run at once;
// COV_CLEAN=1 builds every workspace crate again first.

import { spawn, spawnSync } from 'node:child_process'
import { mkdirSync, openSync, writeFileSync } from 'node:fs'
import { availableParallelism } from 'node:os'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'

const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const [spaces, ignore] = process.argv.slice(2)
const cargo = ['run', 'stable', 'cargo']
const jobs = Number(process.env.COV_JOBS) || Math.max(2, Math.floor(availableParallelism() / 2))
const started = Date.now()
const took = () => `${((Date.now() - started) / 1000).toFixed(0)}s`

/// Runs `rustup run stable cargo <args>`, its output shown, failing with it.
const run = (args, env = process.env, opts = {}) => {
  const r = spawnSync('rustup', [...cargo, ...args], { cwd: root, env, stdio: 'inherit', ...opts })
  if (r.status !== 0) process.exit(r.status ?? 1)
  return r
}

// What cargo-llvm-cov sets to build and run instrumented, in its own
// target directory, as `cargo llvm-cov` uses.
const target = join(root, 'target/llvm-cov-target')
const shown = spawnSync('rustup', [...cargo, 'llvm-cov', 'show-env', '--sh'], {
  cwd: root,
  env: { ...process.env, CARGO_TARGET_DIR: target },
  encoding: 'utf8',
})
const env = { ...process.env, CARGO_TARGET_DIR: target }
for (const [, k, v] of shown.stdout.matchAll(/^export ([A-Z_0-9]+)=(.*)$/gm)) env[k] = v.replace(/^'(.*)'$/, '$1')

// Only the last run's counts are cleared, so only what changed is built
// again. A binary left from an older build adds no counts, only regions
// none ran, so it can fail the gate but never pass it: COV_CLEAN=1 clears
// them too, as after a miss that makes no sense.
run(['llvm-cov', 'clean', process.env.COV_CLEAN ? '--workspace' : '--profraw-only'])

// The harnesses start while the tests build.
mkdirSync(join(root, 'target'), { recursive: true })
const harness = (name, devEnv) => {
  const file = join(root, `target/cov-net-${name}.json`)
  // What the PDS logs, which tests provoke on purpose, is kept out of the way.
  const log = openSync(join(root, `target/cov-net-${name}.log`), 'w')
  const child = spawn('node', [join(root, 'harness/pds.mjs'), '--accounts', 'seed'], {
    cwd: root,
    env: { ...process.env, KNOTLESS_DEV_ENV: devEnv },
    stdio: ['pipe', 'pipe', log],
  })
  const up = new Promise((ok, fail) => {
    let out = ''
    child.stdout.on('data', (d) => {
      out += d
      if (!out.includes('\n')) return
      writeFileSync(file, out)
      ok(file)
    })
    child.on('exit', (code) => fail(new Error(`the ${name} harness exited with ${code}: target/cov-net-${name}.log`)))
  })
  return { up, stop: () => child.stdin.end() }
}
const nets = { stock: harness('stock', ''), spaces: harness('spaces', spaces) }
const stop = () => Object.values(nets).forEach((n) => n.stop())
process.on('exit', stop)

// Every test binary, and the package it is in: cargo runs each there.
const built = spawnSync('rustup', [...cargo, 'test', '--workspace', '--no-run', '--message-format=json'], {
  cwd: root,
  env,
  encoding: 'utf8',
  stdio: ['ignore', 'pipe', 'inherit'],
  maxBuffer: 1 << 28,
})
if (built.status !== 0) process.exit(built.status ?? 1)
const tests = built.stdout
  .split('\n')
  .filter((l) => l.startsWith('{'))
  .map((l) => JSON.parse(l))
  .filter((m) => m.reason === 'compiler-artifact' && m.profile?.test && m.executable)
  .map((m) => ({ exe: m.executable, dir: dirname(m.manifest_path), name: `${m.target.name} (${m.target.kind[0]})` }))
console.log(`built ${tests.length} test binaries in ${took()}`)

const files = Object.fromEntries(await Promise.all(Object.entries(nets).map(async ([k, n]) => [k, await n.up])))
// The integration tests first: they take longest, so start soonest.
const slow = (t) => (t.name.endsWith('(test)') ? 0 : 1)
const runs = Object.keys(files)
  .flatMap((net) => tests.map((t) => ({ ...t, net })))
  .sort((a, b) => slow(a) - slow(b))

/// One binary against one harness, its output kept to show if it fails.
const one = (t) =>
  new Promise((ok) => {
    const child = spawn(t.exe, [], {
      cwd: t.dir,
      env: {
        ...env,
        KNOTLESS_TEST_NET: files[t.net],
        KNOTLESS_DEV_ENV: t.net === 'spaces' ? spaces : '',
        CARGO_MANIFEST_DIR: t.dir,
        // As .cargo/config.toml sets them for cargo: where the answers'
        // TypeScript types are written.
        TS_RS_EXPORT_DIR: join(root, 'web/src/lib/api'),
        TS_RS_LARGE_INT: 'number',
      },
      stdio: ['ignore', 'pipe', 'pipe'],
    })
    let out = ''
    child.stdout.on('data', (d) => (out += d))
    child.stderr.on('data', (d) => (out += d))
    child.on('exit', (code) => ok({ ...t, code, out }))
  })

const failed = []
let next = 0
await Promise.all(
  Array.from({ length: jobs }, async () => {
    while (next < runs.length) {
      const r = await one(runs[next++])
      const line = r.out.match(/^test result: .*$/m)?.[0] ?? `exited with ${r.code}`
      console.log(`${r.code === 0 ? 'ok  ' : 'FAIL'} ${r.net.padEnd(6)} ${r.name}: ${line}`)
      if (r.code !== 0) failed.push(r)
    }
  }),
)
stop()
for (const r of failed) console.log(`\n---- ${r.net} ${r.name}\n${r.out}`)
if (failed.length) process.exit(1)
console.log(`ran ${runs.length} in ${took()}`)

run(['llvm-cov', 'report', '--ignore-filename-regex', ignore, '--fail-under-lines', '100', '--fail-under-functions', '100', '--show-missing-lines'])
console.log(`coverage in ${took()}`)