Core Utils Breakdown Tests

This commit is contained in:
Raven Scott
2026-04-26 15:05:19 -04:00
parent e59c57e538
commit 9471788f6b
8 changed files with 44516 additions and 6 deletions
+5 -1
View File
@@ -1,7 +1,7 @@
{ {
"schema": 2, "schema": 2,
"profileId": "bare-os-posix-like", "profileId": "bare-os-posix-like",
"generatedAt": "2026-04-26T12:56:08.959Z", "generatedAt": "2026-04-26T19:04:18.264Z",
"note": "Sparse POSIX Issue 7 coverage hints for /bin utilities. Omitted command names are not yet profiled here.", "note": "Sparse POSIX Issue 7 coverage hints for /bin utilities. Omitted command names are not yet profiled here.",
"commandIndex": [ "commandIndex": [
{ {
@@ -20,6 +20,10 @@
"name": "awk", "name": "awk",
"tier": "tier1_bin" "tier": "tier1_bin"
}, },
{
"name": "bare-sshd",
"tier": "tier1_bin"
},
{ {
"name": "baresay", "name": "baresay",
"tier": "tier1_bin" "tier": "tier1_bin"
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"schema": 1, "schema": 1,
"atMs": 1777208168958, "atMs": 1777230258263,
"commands": [ "commands": [
"agent", "agent",
"appctl", "appctl",
+22109 -1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -36,6 +36,7 @@
"os:booter": "node scripts/ensure-pear-node-modules.mjs packages/bare-os-booter && cd packages/bare-os-booter && pear run --dev .", "os:booter": "node scripts/ensure-pear-node-modules.mjs packages/bare-os-booter && cd packages/bare-os-booter && pear run --dev .",
"vendor:bare-node-shims": "node scripts/vendor-bare-node-shims.mjs", "vendor:bare-node-shims": "node scripts/vendor-bare-node-shims.mjs",
"smoke:agent-web-fetch:bare": "bare scripts/smoke-agent-web-fetch-bare.mjs", "smoke:agent-web-fetch:bare": "bare scripts/smoke-agent-web-fetch-bare.mjs",
"probe:kernel-bin": "node scripts/probe-kernel-bin.mjs",
"sample:agent-workspace": "node scripts/print-agent-workspace-sample.mjs", "sample:agent-workspace": "node scripts/print-agent-workspace-sample.mjs",
"md:rendered-asterisks:check": "node scripts/fix-markdown-rendered-asterisks.mjs", "md:rendered-asterisks:check": "node scripts/fix-markdown-rendered-asterisks.mjs",
"md:rendered-asterisks:fix": "node scripts/fix-markdown-rendered-asterisks.mjs --write" "md:rendered-asterisks:fix": "node scripts/fix-markdown-rendered-asterisks.mjs --write"
@@ -1,7 +1,7 @@
{ {
"schema": 2, "schema": 2,
"profileId": "bare-os-posix-like", "profileId": "bare-os-posix-like",
"generatedAt": "2026-04-26T12:56:08.959Z", "generatedAt": "2026-04-26T19:04:18.264Z",
"note": "Sparse POSIX Issue 7 coverage hints for /bin utilities. Omitted command names are not yet profiled here.", "note": "Sparse POSIX Issue 7 coverage hints for /bin utilities. Omitted command names are not yet profiled here.",
"commandIndex": [ "commandIndex": [
{ {
@@ -20,6 +20,10 @@
"name": "awk", "name": "awk",
"tier": "tier1_bin" "tier": "tier1_bin"
}, },
{
"name": "bare-sshd",
"tier": "tier1_bin"
},
{ {
"name": "baresay", "name": "baresay",
"tier": "tier1_bin" "tier": "tier1_bin"
@@ -1,6 +1,6 @@
{ {
"schema": 1, "schema": 1,
"atMs": 1777208168958, "atMs": 1777230258263,
"commands": [ "commands": [
"agent", "agent",
"appctl", "appctl",
File diff suppressed because one or more lines are too long
+285
View File
@@ -0,0 +1,285 @@
#!/usr/bin/env node
import b4a from 'b4a'
import Corestore from 'corestore'
import Hyperdrive from 'hyperdrive'
import os from 'node:os'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import {
mkdtemp,
readdir,
readFile,
rm
} from 'node:fs/promises'
import { COREUTILS_COMMANDS } from '../packages/bare-os-coreutils/lib/commands.mjs'
import { createBareOsIpc } from '../packages/bare-os-booter/lib/bare-os-ipc.js'
import { runBinCommand } from '../packages/bare-os-booter/lib/kernel-runner.js'
import { createVfs } from '../packages/bare-os-booter/lib/vfs.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const root = path.resolve(__dirname, '..')
const kernelBinDir = path.join(root, 'kernel', 'bin')
const probeTimeoutMs = Number.parseInt(process.env.BARE_OS_BIN_PROBE_TIMEOUT_MS || '', 10) || 2_000
const truncLen = 160
const FAST_SAFE_ARGS = new Map([
['echo', ['ok']],
['false', []],
['nice', ['true']],
['nohup', ['true']],
['printf', ['ok']],
['pwd', []],
['test', ['1', '=', '1']],
['time', ['true']],
['timeout', ['1', 'true']],
['true', []]
])
const HELP_ONLY_ARGS = new Map([
['sshd', ['-h']]
])
const SKIPPED = new Map([])
function classifyNonZero(exitCode, combinedText) {
if (exitCode === 0) return 'OK'
if (exitCode === 126 && /delegate/i.test(combinedText)) return 'SKIPPED'
if (exitCode === 1 || exitCode === 2) {
if (
/(usage|--help|help|unknown option|unrecognized|illegal option|invalid option|requires tty|not supported)/i.test(
combinedText
)
) {
return 'USAGE'
}
return 'NOHELP'
}
return 'EXCEPTION'
}
function shortText(lines) {
const joined = lines.join('\n').replace(/\s+/g, ' ').trim()
if (joined.length <= truncLen) return joined
return joined.slice(0, truncLen) + '...'
}
function probeArgvFor(name) {
if (FAST_SAFE_ARGS.has(name)) return [name, ...FAST_SAFE_ARGS.get(name)]
if (HELP_ONLY_ARGS.has(name)) return [name, ...HELP_ONLY_ARGS.get(name)]
return [name, '--help']
}
async function loadKernelBinNames() {
const ents = await readdir(kernelBinDir, { withFileTypes: true })
return ents
.filter((ent) => ent.isFile())
.map((ent) => ent.name)
.sort((a, b) => a.localeCompare(b))
}
async function seedSystemDrive(drive, names) {
for (const name of names) {
const src = await readFile(path.join(kernelBinDir, name), 'utf8')
await drive.put('/bin/' + name, b4a.from(src))
}
}
async function makeProbeContext() {
const tmp = await mkdtemp(path.join(os.tmpdir(), 'bare-os-bin-probe-'))
const store = new Corestore(tmp)
const drive = new Hyperdrive(store)
const personal = new Hyperdrive(store.namespace('probe-personal'))
await drive.ready()
await personal.ready()
const env = {
HOME: '/home/user',
PATH: '/bin',
USER: 'user',
UID: '1000',
GID: '1000',
PWD: '/home/user',
BARE_OS_EXIT_STATUS: '0',
BARE_OS_RUNBIN_DEFAULT_TIMEOUT_MS: String(probeTimeoutMs),
BARE_OS_DELEGATE_ALLOW: 'none',
BARE_OS_DELEGATE_AUDIT_ONLY: '1',
BARE_OS_AUDIT: '1'
}
const bareOsIpc = createBareOsIpc()
const vfs = createVfs(drive, personal, env, null, { bareOsIpc })
const logs = []
const errs = []
const ctx = {
drive,
personalDrive: personal,
vfs,
bareOsIpc,
env,
b4a,
exitCode: 0,
console: {
log: (...a) => logs.push(a.join(' ')),
error: (...a) => errs.push(a.join(' '))
},
async bareOsRunCurlCli() {
errs.push('delegate disabled: curl')
this.exitCode = 126
},
async bareOsRunWgetCli() {
errs.push('delegate disabled: wget')
this.exitCode = 126
}
}
ctx.runBinCommand = function runSelf(argv, opts) {
return runBinCommand(this, argv, opts)
}
return { tmp, store, drive, personal, logs, errs, ctx }
}
async function main() {
const coreutils = [...COREUTILS_COMMANDS].sort((a, b) => a.localeCompare(b))
const staged = await loadKernelBinNames()
const stagedSet = new Set(staged)
const coreSet = new Set(coreutils)
const missing = coreutils.filter((name) => !stagedSet.has(name))
const extra = staged.filter((name) => !coreSet.has(name))
const candidates = [...new Set([...coreutils, ...staged])].sort((a, b) =>
a.localeCompare(b)
)
const { tmp, store, drive, personal, logs, errs, ctx } = await makeProbeContext()
let failed = false
/** @type {Array<{name:string,status:string,argv:string[],exitCode:number|null,durationMs:number,stdout:string,stderr:string,note?:string}>} */
const results = []
try {
await seedSystemDrive(drive, staged)
for (const name of candidates) {
if (!stagedSet.has(name)) {
results.push({
name,
status: 'MISSING',
argv: [],
exitCode: null,
durationMs: 0,
stdout: '',
stderr: '',
note: 'Listed in COREUTILS_COMMANDS but missing from kernel/bin'
})
continue
}
if (SKIPPED.has(name)) {
results.push({
name,
status: 'SKIPPED',
argv: [name],
exitCode: null,
durationMs: 0,
stdout: '',
stderr: '',
note: SKIPPED.get(name)
})
continue
}
const argv = probeArgvFor(name)
logs.length = 0
errs.length = 0
ctx.exitCode = 0
const started = Date.now()
try {
await runBinCommand(ctx, argv, { timeoutMs: probeTimeoutMs })
const durationMs = Date.now() - started
const stdout = shortText(logs)
const stderr = shortText(errs)
const merged = `${stdout}\n${stderr}`.trim()
const status = classifyNonZero(ctx.exitCode || 0, merged)
results.push({
name,
status,
argv,
exitCode: ctx.exitCode ?? null,
durationMs,
stdout,
stderr
})
} catch (err) {
const durationMs = Date.now() - started
const msg = err instanceof Error ? err.message : String(err)
const timeout = /timeout|timed out|abort/i.test(msg)
results.push({
name,
status: timeout ? 'TIMEOUT' : 'EXCEPTION',
argv,
exitCode: ctx.exitCode ?? null,
durationMs,
stdout: shortText(logs),
stderr: shortText([...errs, msg])
})
}
}
} finally {
await personal.close()
await drive.close()
await store.close()
await rm(tmp, { recursive: true, force: true })
}
for (const r of results) {
if (!coreSet.has(r.name) && r.status !== 'MISSING') r.note = 'EXTRA staged bin'
}
const counts = new Map()
for (const r of results) counts.set(r.status, (counts.get(r.status) || 0) + 1)
if (extra.length) counts.set('EXTRA', extra.length)
const broken = results.filter((r) =>
['TIMEOUT', 'EXCEPTION'].includes(r.status)
)
if (broken.length > 0 || missing.length > 0) failed = true
const order = [
'OK',
'USAGE',
'NOHELP',
'SKIPPED',
'MISSING',
'EXTRA',
'TIMEOUT',
'EXCEPTION'
]
console.log('BINS PROBE SUMMARY')
console.log('==================')
console.log(`COREUTILS_COMMANDS: ${coreutils.length}`)
console.log(`kernel/bin files: ${staged.length}`)
console.log(`Candidates probed: ${results.length}`)
console.log(`Timeout per bin: ${probeTimeoutMs}ms`)
for (const key of order) {
const n = counts.get(key)
if (n) console.log(`${key}: ${n}`)
}
console.log('')
for (const r of results) {
if (r.status === 'OK' || r.status === 'USAGE' || r.status === 'NOHELP') continue
const ec = r.exitCode == null ? 'n/a' : String(r.exitCode)
const probe = r.argv.length ? r.argv.join(' ') : '(none)'
const detail = r.stderr || r.stdout || r.note || ''
console.log(`${r.status} ${r.name} | exit=${ec} | argv=${probe}`)
if (detail) console.log(` ${detail}`)
}
if (failed) {
process.exitCode = 1
return
}
process.exitCode = 0
}
main().catch((err) => {
const msg = err instanceof Error ? err.stack || err.message : String(err)
console.error(msg)
process.exit(1)
})