import test from 'brittle' import b4a from 'b4a' import Hyperdrive from 'hyperdrive' import Corestore from 'corestore' import { mkdirSync, rmSync } from 'node:fs' import { readFile, readdir } from 'node:fs/promises' import path from 'node:path' import { fileURLToPath } from 'node:url' import { createRequire } from 'node:module' import { PassThrough } from 'node:stream' import { runKernelFromSource, runBinCommand } from './lib/kernel-runner.js' import { createGitFsFromVfs } from './lib/git-fs-adapter.js' import { runGitCli } from './lib/git-cli.js' import { createStreamLineReader } from './lib/cli-readline.js' import { createVfs, BARE_OS_PROC_FILE_TO_ID_HYPERCORE_PACK_HRPC_LIFECYCLE } from './lib/vfs.js' import { buildBareOsHypercorePackHrpcLifecycleProcJson } from './lib/bare-os-proc-hypercore-pack-hrpc-lifecycle.js' import { buildBareOsPearCorestoreHrpcProcJson } from './lib/bare-os-proc-pear-corestore-hrpc.js' import { buildBareOsPearInspectLoggerTlsProcJson } from './lib/bare-os-proc-pear-inspect-logger-tls.js' import { buildBareOsBareRuntimeProtoMuxProcJson } from './lib/bare-os-proc-bare-runtime-proto-mux.js' import { pathnameExpandShellWord } from './lib/shell-glob.js' import { createBareOsIpc } from './lib/bare-os-ipc.js' import { topologicalOrderKernelExtensions } from './lib/kernel-extension-resolver.js' import { createBareOsProtomuxAliasRegistry } from './lib/bare-os-protomux-alias-registry.js' import { bareOsHttpUrlAllowed } from './lib/bare-os-http-policy.js' import { bareOsParseBareAclText, bareOsAclDeniesSubject } from './lib/bare-os-vfs-acl-enforce.js' import { raceWithAbortAndTimeout } from './lib/bare-os-abort.js' import { tokenize, expandWord, execShellLine, expandArgvAliases, defaultShellAliases, loadBarerc, BARERC_SKELETON, splitTokensBySemicolon, splitTokensByAndOr, BARE_OS_EXIT_STATUS_ENV, syncBareOsExitStatusEnv, getBareOsPipelineLimits, DEFAULT_PIPELINE_MAX_STAGES, } from './lib/shell.js' import { applyBareOsThemeFromEnv, bareOsListThemeNames } from './lib/bare-os-theme-presets.js' import { bareParseLsColors, bareSerializeLsColors, bareLsColorOpenSgrFromMap, bareDefaultDircolorsDatabase, bareParseDircolorsDatabase } from 'bare-os-lscolors' import { BARE_OS_CTX_API_VERSION } from './lib/bare-os-ctx-api.js' import { buildBareOsRuntimeCaps } from './lib/bare-os-runtime-caps.js' import { bareOsBareModulesEnabled, bareOsBareModuleManifestEmbeddedRef, buildBareCtxObjectFromHost, loadBareModuleManifest, maybeMergeBareFromDrive } from './lib/bare-os-ctx-bare.js' import { maybeBareOsBuildBinManifest } from './lib/bare-os-bin-index.js' import { fuzzyMatch, stripAnsi, parseHistoryFile, formatHistoryFile, dedupeConsecutiveHistory, searchHistoryEntries } from './lib/fish-readline.js' import { fieldMatches, dowFieldMatches, parseCronLine, jobMatchesDate } from './lib/bare-cron.js' import { bareInitdReadinessSnapshot, bareInitdShutdownActiveUnitsReverse, getBareServiceRuntime, registerBareInitdDisposer, registerKernelShutdownHook, runKernelShutdownHooks, startBareInitd, stopBareInitd, getLastBareInitdDagSnapshotJson } from './lib/bare-initd.js' import { parseUnitDropInText } from './lib/bare-initd-user.js' import { bareOsProcessTableSnapshot } from './lib/bare-os-process-table.js' import { buildBareOsSyscallsProcJson } from './lib/bare-os-syscalls-proc-json.js' import { bareOsParseSendmsgScmRights, wantPosixSocketScmRights } from './lib/bare-os-socket-scm-rights.js' import { parseBareOsHrpcAllowlistJson, bareOsHrpcAllowlistDeniesRoute } from './lib/bare-os-hrpc-allowlist.js' import { buildBareOsProtomuxExtensionsProcJson } from './lib/bare-os-protomux-extensions-proc.js' import { createBareOsDiskOsBridge } from './lib/bare-os-disk-os-bridge.js' import { buildBareOsReplicationLiveSketch } from './lib/bare-os-replication-proc-live.js' import { evaluateBareOsPeerAdmission } from './lib/bare-os-peer-admission.js' import { buildBareOsReplicationOperatorSurfaceProcJson } from './lib/bare-os-proc-replication-operator-surface.js' import { DEFAULT_CURL_USER_AGENT, DEFAULT_WGET_USER_AGENT } from './lib/http-fetch-url.js' import { filenameFromContentDisposition } from './lib/curl-cli.js' import { encodeUstarHeader, runTarCli } from './lib/tar-cli.js' const require = createRequire(import.meta.url) const __dirname = path.dirname(fileURLToPath(import.meta.url)) const TAR_BLK = 512 /** @param {Uint8Array[]} parts */ function concatTarParts(parts) { let n = 0 for (const p of parts) n += p.length const out = new Uint8Array(n) let o = 0 for (const p of parts) { out.set(p, o) o += p.length } return out } function headerFromInit(init, name) { if (!init?.headers) return undefined const h = init.headers if (typeof h.get === 'function') return h.get(name) return undefined } function testCorestoreDir(name) { const dir = path.join( __dirname, '.test-data', name + '-' + process.pid + '-' + Math.random().toString(36).slice(2) ) mkdirSync(path.dirname(dir), { recursive: true }) return dir } function testCtx(drive, personal, env) { const shellEnv = { HOME: '/home/user', PATH: '/bin', USER: 'user', UID: '1000', GID: '1000', PWD: '/home/user', BARE_OS_EXIT_STATUS: '0', ...env } const bareOsIpc = createBareOsIpc() const vfs = createVfs(drive, personal, shellEnv, null, { bareOsIpc }) const ctx = { drive, personalDrive: personal, vfs, bareOsIpc, env: shellEnv, console, b4a, async bareOsApplyTheme() { return applyBareOsThemeFromEnv(this) }, bareOsListThemes() { return bareOsListThemeNames() } } return ctx } /** Personal-drive path backing logical `/home//…` (matches `vfs.js`). */ function personalHomeBacking(homePath, rel = '') { const seg = homePath.replace(/^\/home\//, '').split('/')[0] || 'user' const r = String(rel).replace(/^\//, '') return r ? `/.bare-os/home/${seg}/${r}` : `/.bare-os/home/${seg}` } test('kernel_program proc JSON includes program metadata', async (t) => { const o = buildBareOsHypercorePackHrpcLifecycleProcJson( 'kernel_program', { BARE_OS_BOOT_SAFE_MODE: '1' } ) t.is(o.schema, 2) t.is(o.program, 'bare-os-kernel-program') t.ok(o.operatorSketches && typeof o.operatorSketches === 'object') t.ok(o.hooks && o.hooks.bootSafeMode === true) }) test('giant_phase_program proc id returns same builder as kernel_program', async (t) => { const a = buildBareOsHypercorePackHrpcLifecycleProcJson('kernel_program', {}) const b = buildBareOsHypercorePackHrpcLifecycleProcJson('giant_phase_program', {}) t.is(a.program, b.program) t.is(a.schema, b.schema) }) test('parseUnitDropInText parses ConditionPathExists and Restart keys', async (t) => { const d = parseUnitDropInText( '[Unit]\nConditionPathExists=/tmp/x\nRestart=on-failure\nRestartSec=2\n' ) t.is(d.conditionPathExists, '/tmp/x') t.is(d.restart, 'on-failure') t.is(d.restartSec, 2) }) test('bareOsIpc.signalProcessGroup pushes bareOsProcessGroupSignal to scoped channels', async (t) => { const ipc = createBareOsIpc() ipc.create('c1') ipc.create('c2') ipc.assignProcessGroup('c1', 7) ipc.assignProcessGroup('c2', 7) const p1 = ipc.takeJson('c1') const p2 = ipc.takeJson('c2') const out = ipc.signalProcessGroup(7, 'SIGUSR1') t.is(out.delivered, 2) const j1 = await p1 const j2 = await p2 t.is(j1.method, 'bareOsProcessGroupSignal') t.is(j1.signal, 'SIGUSR1') t.is(j2.pgid, 7) const st = ipc.stats() t.ok(st.processGroups && st.processGroups.byPgid) t.ok(st.processGroups.byPgid['pgid:7'].includes('c1')) }) test('kernel ext incremental reload runs only new scripts when hot reload env set', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) /** @type {string[]} */ const extDir = ['01-a.json'] /** @type {string[]} */ const ran = [] const vfsFiles = new Map() const drive = { async get(p) { if (p === '/etc/os-release') return b4a.from('ID=test\n') if (p === '/etc/motd') return b4a.from('') if (p === '/etc/bare-os/kernel.ext.d/01-a.json') { return b4a.from( JSON.stringify({ id: 'a', scripts: ['/lib/bare-os/extensions/a.js'] }) ) } if (p === '/etc/bare-os/kernel.ext.d/02-b.json') { return b4a.from( JSON.stringify({ id: 'b', scripts: ['/lib/bare-os/extensions/b.js'] }) ) } return null }, async *readdir(d) { if (d === '/etc/bare-os/kernel.ext.d') { for (const x of extDir) yield x } } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_BOOT_SKIP_STAGES: 'profile,rc,rc.d,rc.local,kernel.d,onboot,selftest', BARE_OS_KERNEL_EXT_D_HOT_RELOAD: '1' }, drive, b4a, vfs: { async readFile(p) { return vfsFiles.get(p) ?? null }, async writeFile(p, body) { vfsFiles.set( p, body instanceof Uint8Array ? body : b4a.from(String(body)) ) } }, console: { log() {}, error() {}, warn() {} }, readLine: async () => null, async execLine() { return 'ok' }, async bareOsRunImageScript(path) { ran.push(path) } } await runKernelFromSource(src, ctx) t.alike(ran, ['/lib/bare-os/extensions/a.js']) t.ok(typeof ctx.bareOsReloadKernelExtDropinsSafe === 'function') extDir.push('02-b.json') const out = await ctx.bareOsReloadKernelExtDropinsSafe() t.ok(out.ok) t.alike(out.ranScripts, ['/lib/bare-os/extensions/b.js']) t.alike(ran, [ '/lib/bare-os/extensions/a.js', '/lib/bare-os/extensions/b.js' ]) const jr = b4a.toString(vfsFiles.get('/run/bare-os/kernel-ext-reload.ndjson')) t.ok(jr.includes('incremental')) }) test('kernel.ext.d minCtxApiVersion skips drop-in when ctx API too low', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) /** @type {string[]} */ const ran = [] const drive = { async get(p) { if (p === '/etc/os-release') return b4a.from('ID=test\n') if (p === '/etc/motd') return b4a.from('') if (p === '/etc/bare-os/kernel.ext.d/01-hi.json') { return b4a.from( JSON.stringify({ id: 'hi', minCtxApiVersion: '99.0.0', scripts: ['/lib/bare-os/extensions/hi.js'] }) ) } return null }, async *readdir(d) { if (d === '/etc/bare-os/kernel.ext.d') yield '01-hi.json' } } const ctx = { bareOsSkipRepl: true, bareOsCtxApiVersion: '1.0.0', env: { BARE_OS_BOOT_SKIP_STAGES: 'profile,rc,rc.d,rc.local,kernel.d,onboot,selftest' }, drive, b4a, console: { log() {}, error() {}, warn() {} }, readLine: async () => null, async execLine() { return 'ok' }, async bareOsRunImageScript(path) { ran.push(path) } } await runKernelFromSource(src, ctx) t.is(ran.length, 0) }) test('kernel.ext.d conflictsWith strict skips extension scripts', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) /** @type {string[]} */ const ran = [] const drive = { async get(p) { if (p === '/etc/os-release') return b4a.from('ID=test\n') if (p === '/etc/motd') return b4a.from('') if (p === '/etc/bare-os/kernel.ext.d/01-a.json') { return b4a.from( JSON.stringify({ id: 'a', conflictsWith: ['b'], scripts: ['/lib/bare-os/extensions/a.js'] }) ) } if (p === '/etc/bare-os/kernel.ext.d/02-b.json') { return b4a.from( JSON.stringify({ id: 'b', scripts: ['/lib/bare-os/extensions/b.js'] }) ) } return null }, async *readdir(d) { if (d === '/etc/bare-os/kernel.ext.d') { yield '01-a.json' yield '02-b.json' } } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_BOOT_SKIP_STAGES: 'profile,rc,rc.d,rc.local,kernel.d,onboot,selftest', BARE_OS_BOOT_POLICY_STRICT: '1' }, drive, b4a, console: { log() {}, error() {}, warn() {} }, readLine: async () => null, async execLine() { return 'ok' }, async bareOsRunImageScript(p) { ran.push(p) } } await runKernelFromSource(src, ctx) t.is(ran.length, 0) }) test('kernel.ext.d dependency cycle strict skips extension scripts', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) /** @type {string[]} */ const ran = [] const drive = { async get(p) { if (p === '/etc/os-release') return b4a.from('ID=test\n') if (p === '/etc/motd') return b4a.from('') if (p === '/etc/bare-os/kernel.ext.d/01-a.json') { return b4a.from( JSON.stringify({ id: 'a', dependsOn: ['b'], scripts: ['/lib/bare-os/extensions/a.js'] }) ) } if (p === '/etc/bare-os/kernel.ext.d/02-b.json') { return b4a.from( JSON.stringify({ id: 'b', dependsOn: ['a'], scripts: ['/lib/bare-os/extensions/b.js'] }) ) } return null }, async *readdir(d) { if (d === '/etc/bare-os/kernel.ext.d') { yield '01-a.json' yield '02-b.json' } } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_BOOT_SKIP_STAGES: 'profile,rc,rc.d,rc.local,kernel.d,onboot,selftest', BARE_OS_BOOT_POLICY_STRICT: '1' }, drive, b4a, console: { log() {}, error() {}, warn() {} }, readLine: async () => null, async execLine() { return 'ok' }, async bareOsRunImageScript(p) { ran.push(p) } } await runKernelFromSource(src, ctx) t.is(ran.length, 0) }) test('stock kernel BARE_OS_BOOT_SAFE_MODE skips kernel.ext.d scripts', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) let extRan = false const drive = { async get(p) { if (p === '/etc/bare-os/kernel.ext.d/01-a.json') { return b4a.from( JSON.stringify({ id: 'a', scripts: ['/lib/bare-os/extensions/x.js'] }) ) } return null }, async *readdir(d) { if (d === '/etc/bare-os/kernel.ext.d') yield '01-a.json' } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_BOOT_SAFE_MODE: '1' }, drive, b4a, console: { log() {}, error() {} }, readLine: async () => null, async execLine() { return 'ok' }, async bareOsRunImageScript() { extRan = true } } await runKernelFromSource(src, ctx) t.is(extRan, false) }) test('runKernelFromSource invokes start(ctx)', async (t) => { const calls = [] const source = ` async function start(ctx) { ctx.calls.push('ok') } ` await runKernelFromSource(source, { calls }) t.is(calls[0], 'ok') }) test('stock kernel init.js onboot runs multiple BARE_OS_ONBOOT lines when SKIP_REPL', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) const execLines = [] const drive = { async get() { return null }, async *readdir() { /* empty */ } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_ONBOOT: 'echo one\n#c\n echo two' }, drive, b4a, console: { log() {}, error() {} }, readLine: async () => null, async execLine(line) { execLines.push(String(line).trim()) return 'ok' } } await runKernelFromSource(src, ctx) t.alike(execLines, ['echo one', 'echo two']) }) test('stock kernel init.js runs rc.local before onboot', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) const execLines = [] const drive = { async get(p) { if (p === '/etc/bare-os/rc.local') return b4a.from('echo rc-local') return null }, async *readdir() { /* empty */ } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_ONBOOT: 'echo onboot-line' }, drive, b4a, console: { log() {}, error() {} }, readLine: async () => null, async execLine(line) { execLines.push(String(line).trim()) return 'ok' } } await runKernelFromSource(src, ctx) t.is(execLines[0], 'echo rc-local') t.is(execLines[1], 'echo onboot-line') }) test('stock kernel init.js runs kernel.d after rc.local before onboot', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) const execLines = [] const drive = { async get(p) { if (p === '/etc/bare-os/rc.local') return b4a.from('echo rc-local') if (p === '/etc/bare-os/kernel.d/05-k.mod') return b4a.from('echo kmod') return null }, async *readdir(dir) { if (dir === '/etc/bare-os/kernel.d') yield '05-k.mod' } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_ONBOOT: 'echo onboot-line' }, drive, b4a, console: { log() {}, error() {} }, readLine: async () => null, async execLine(line) { execLines.push(String(line).trim()) return 'ok' } } await runKernelFromSource(src, ctx) t.is(execLines[0], 'echo rc-local') t.is(execLines[1], 'echo kmod') t.is(execLines[2], 'echo onboot-line') }) test('stock kernel init.js BARE_OS_BOOT_TRACE=json emits boot trace JSON on stderr', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) const stderr = [] const drive = { async get() { return null }, async *readdir() { /* empty */ } } const ctx = { bareOsSkipRepl: false, env: { BARE_OS_BOOT_TRACE: 'json' }, drive, b4a, console: { log() {}, error(...a) { stderr.push(a.join(' ')) } }, readLine: async () => null, async execLine() { return 'ok' } } await runKernelFromSource(src, ctx) const phases = stderr .map((l) => { try { return JSON.parse(l) } catch { return null } }) .filter(Boolean) const bootSteps = phases.filter( (o) => o && typeof o.ms === 'number' && o.type !== 'bootOutput' ) t.ok(bootSteps.length >= 3) t.ok(bootSteps.some((o) => o.phase === 'rc.local')) t.ok(bootSteps.some((o) => o.step === 'rc.local')) t.ok(bootSteps.some((o) => o.phase === 'kernel.d')) t.ok(bootSteps.some((o) => o.step === 'kernel.d')) t.ok(bootSteps.every((o) => o.bootTraceSchemaVersion === 2)) t.ok(bootSteps.every((o) => typeof o.ms === 'number')) t.ok( phases.some( (o) => o && o.type === 'bootOutput' && o.step === 'banner' ), 'bootOutput trace for guest-visible banner' ) }) test('stock kernel BARE_OS_RC_D_SKIP skips matching rc.d snippets', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) const execLines = [] const drive = { async get(p) { if (p === '/etc/bare-os/rc.d/05-skip.me') return b4a.from('echo skipped-should-not-run') if (p === '/etc/bare-os/rc.d/10-keep') return b4a.from('echo kept') return null }, async *readdir(dir) { if (dir === '/etc/bare-os/rc.d') { yield '05-skip.me' yield '10-keep' } } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_ONBOOT: 'echo tail', BARE_OS_RC_D_SKIP: '05-*' }, drive, b4a, console: { log() {}, error() {} }, readLine: async () => null, async execLine(line) { execLines.push(String(line).trim()) return 'ok' } } await runKernelFromSource(src, ctx) t.ok(!execLines.some((l) => l.includes('skipped'))) t.is(execLines[0], 'echo kept') t.is(execLines[1], 'echo tail') }) test('stock kernel BARE_OS_BOOT_STRICT stops boot after execLine throw', async (t) => { const src = await readFile( path.join(__dirname, '../../kernel/init.js'), 'utf8' ) const execLines = [] let exitArg = null const drive = { async get(p) { if (p === '/etc/bare-os/rc') return b4a.from('echo first\n__throw__\necho third') return null }, async *readdir() { /* empty */ } } const ctx = { bareOsSkipRepl: true, env: { BARE_OS_BOOT_STRICT: '1' }, drive, b4a, console: { log() {}, error() {} }, readLine: async () => null, requestBooterExit(code) { exitArg = code }, async execLine(line) { const t0 = String(line).trim() if (t0 === '__throw__') throw new Error('boot-fail') execLines.push(t0) return 'ok' } } await runKernelFromSource(src, ctx) t.alike(execLines, ['echo first']) t.is(exitArg, 1) }) test('runBinCommand runs /bin helper', async (t) => { const dir = testCorestoreDir('bin') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('p')) await drive.ready() await personal.ready() await drive.put( '/bin/hello', b4a.from(` async function run(ctx, argv) { ctx.out.push(argv.join(' ')) } `) ) const out = [] const ctx = testCtx(drive, personal) ctx.out = out await runBinCommand(ctx, ['hello', 'a', 'b']) t.is(out[0], 'hello a b') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand runs bare hello.js from cwd on personal drive', async (t) => { const dir = testCorestoreDir('barejs') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pj')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', 'hello.js'), b4a.from(` async function run(ctx, argv) { ctx.out.push(argv.join(' ')) } `) ) const out = [] const ctx = testCtx(drive, personal) ctx.out = out await runBinCommand(ctx, ['hello.js', 'x', 'y']) t.is(out[0], 'hello.js x y') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand strips shebang from user script', async (t) => { const dir = testCorestoreDir('shebang') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psh')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', 'x.js'), b4a.from(`#!/usr/bin/env bare async function run(ctx) { ctx.out.push('ok') } `) ) const out = [] const ctx = testCtx(drive, personal) ctx.out = out await runBinCommand(ctx, ['./x.js']) t.is(out[0], 'ok') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand runs top-level user script without run()', async (t) => { const dir = testCorestoreDir('norun') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pnr')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', 'plain.js'), b4a.from(`ctx.out.push('only-top')`) ) const out = [] const ctx = testCtx(drive, personal) ctx.out = out await runBinCommand(ctx, ['./plain.js']) t.is(out[0], 'only-top') t.is(ctx.exitCode, 0) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand runs top-level then run() when both present', async (t) => { const dir = testCorestoreDir('bothrun') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pbr')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', 'hybrid.js'), b4a.from(`ctx.out.push('first') async function run(ctx) { ctx.out.push('second') } `) ) const out = [] const ctx = testCtx(drive, personal) ctx.out = out await runBinCommand(ctx, ['./hybrid.js']) t.alike(out, ['first', 'second']) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand user script error is caught and logged', async (t) => { const dir = testCorestoreDir('throwjs') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('ptj')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', 'bad.js'), b4a.from(`async function run() { test() }`) ) const errs = [] const ctx = testCtx(drive, personal) ctx.console = { log: () => {}, error: (...a) => { errs.push(a.join(' ')) } } await runBinCommand(ctx, ['./bad.js']) t.ok(errs.length > 0) t.ok(errs.some((e) => /test|not defined|ReferenceError/i.test(e))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ls hides dotfiles unless -a', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const lsSrc = await readFile(lsPath, 'utf8') const dir = testCorestoreDir('lsdot') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pls')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) await personal.put( personalHomeBacking('/home/user', 'shown.txt'), b4a.from('') ) await personal.put(personalHomeBacking('/home/user', '.hidden'), b4a.from('')) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await runBinCommand(ctx, ['ls']) const flat = lines.join('\n') t.ok(flat.includes('shown.txt')) t.ok(!flat.includes('hidden')) lines.length = 0 await runBinCommand(ctx, ['ls', '-a']) const flatA = lines.join('\n') t.ok(flatA.includes('hidden')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('createStreamLineReader yields lines after newline', async (t) => { const stdin = new PassThrough() const chunks = [] const stdout = { write(s) { chunks.push(String(s)) } } const readLine = createStreamLineReader(stdin, stdout) const p = readLine('> ') stdin.write('help\n') t.is(await p, 'help') t.ok(chunks.join('').includes('> ')) stdin.end() }) test('Hyperdrive roundtrips /boot/init.js on Corestore', async (t) => { const dir = testCorestoreDir('seed') const store = new Corestore(dir) const drive = new Hyperdrive(store) await drive.ready() await drive.put('/boot/init.js', b4a.from('async function start() {}')) const buf = await drive.get('/boot/init.js') t.ok(buf) t.is(b4a.toString(buf), 'async function start() {}') await drive.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs lstat personal file includes mode uid user mtime', async (t) => { const dir = testCorestoreDir('lstatposix') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('lsp')) await sys.ready() await personal.ready() const vfs = createVfs(sys, personal, { HOME: '/home/user', PWD: '/home/user', PATH: '/bin', USER: 'alice', UID: '4242', GID: '4242' }) await vfs.writeFile('f', b4a.from('x')) const st = await vfs.lstat('/home/user/f') t.ok(st) t.is(st.type, 'file') t.is(st.user, 'alice') t.is(st.uid, 4242) t.ok((st.mode & 0o777) <= 0o777) t.ok((st.mode & 0o100000) === 0o100000) t.ok(typeof st.mtimeMs === 'number') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs syscalls.json uses schema 8 when provider wired', async (t) => { const dir = testCorestoreDir('syscallsproc') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('scp')) await sys.ready() await personal.ready() const sample = { schemaVersion: 8, ctxApiVersion: BARE_OS_CTX_API_VERSION, ops: ['readFile'], errnoHints: { ENOENT: 2 }, fdModel: { schema: 1, stdio: [0, 1, 2] }, signalModel: { schema: 1, names: ['INT'] }, atMs: 0 } const vfs = createVfs( sys, personal, { HOME: '/home/g', PWD: '/', PATH: '/bin' }, null, { procBareOsSyscallsText() { return `${JSON.stringify(sample)}\n` } } ) const buf = await vfs.readFile('/proc/bare_os/syscalls.json') const j = JSON.parse(b4a.toString(buf)) t.is(j.schemaVersion, 8) t.ok(j.fdModel && j.fdModel.schema === 1) t.ok(j.signalModel && Array.isArray(j.signalModel.names)) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /dev/shm named segment write read unlink roundtrip', async (t) => { const dir = testCorestoreDir('devshm') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('shm')) await sys.ready() await personal.ready() const vfs = createVfs(sys, personal, { HOME: '/home/g', PWD: '/', PATH: '/bin' }) const names0 = (await vfs.readdir('/dev')).slice().sort() t.ok(names0.includes('shm')) await vfs.writeFile('/dev/shm/seg1', b4a.from('abc')) const names1 = await vfs.readdir('/dev/shm') t.ok(names1.includes('seg1')) t.is(b4a.toString(await vfs.readFile('/dev/shm/seg1')), 'abc') await vfs.unlink('/dev/shm/seg1') const names2 = await vfs.readdir('/dev/shm') t.absent(names2.includes('seg1')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /bin warm read cache hit then bareOsClearWarmReadCaches resets', async (t) => { const dir = testCorestoreDir('warmcache') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('wc')) await sys.ready() await personal.ready() await sys.put('/bin/warmX', b4a.from('payload')) const warmRef = { current: null } const env = { HOME: '/home/g', PWD: '/', PATH: '/bin', BARE_OS_VFS_BIN_CACHE: '1' } const vfs = createVfs(sys, personal, env, null, { warmReadCacheStatsRef: warmRef }) await vfs.readFile('/bin/warmX') const h0 = warmRef.current?.hits ?? 0 await vfs.readFile('/bin/warmX') t.ok((warmRef.current?.hits ?? 0) > h0, 'second read should warm-hit') vfs.bareOsClearWarmReadCaches() t.is(warmRef.current?.hits, 0) t.is(warmRef.current?.misses, 0) await vfs.readFile('/bin/warmX') t.ok((warmRef.current?.misses ?? 0) >= 1, 'after clear, read counts as miss again') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs bareOsEvictLibBareBundlesFromManifest evicts only listed bundle paths', async (t) => { const dir = testCorestoreDir('manifestevict') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('me')) await sys.ready() await personal.ready() await sys.put('/lib/bare/bundles/b4a.js', b4a.from('b4a')) await sys.put('/lib/bare/bundles/safetyCatch.js', b4a.from('sc')) const warmRef = { current: null } const env = { HOME: '/home/g', PWD: '/', PATH: '/bin', BARE_OS_VFS_BIN_CACHE: '1', BARE_OS_VFS_LIB_BARE_CACHE: '1' } const vfs = createVfs(sys, personal, env, null, { warmReadCacheStatsRef: warmRef }) await vfs.readFile('/lib/bare/bundles/b4a.js') await vfs.readFile('/lib/bare/bundles/safetyCatch.js') const hitsBefore = warmRef.current?.hits ?? 0 await vfs.readFile('/lib/bare/bundles/b4a.js') t.ok((warmRef.current?.hits ?? 0) > hitsBefore) const manifest = JSON.stringify({ version: 1, entries: [ { ctxKey: 'b4a', package: 'b4a', bundle: true }, { ctxKey: 'xOther', package: 'x', bundle: false } ] }) vfs.bareOsEvictLibBareBundlesFromManifest(b4a.from(manifest)) const missesAfterEvict = warmRef.current?.misses ?? 0 await vfs.readFile('/lib/bare/bundles/b4a.js') t.ok( (warmRef.current?.misses ?? 0) > missesAfterEvict, 'b4a should miss after selective evict' ) const hitsSc = warmRef.current?.hits ?? 0 await vfs.readFile('/lib/bare/bundles/safetyCatch.js') t.ok( (warmRef.current?.hits ?? 0) > hitsSc, 'safetyCatch still served from warm cache' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('blind relay / pairing / geo proc JSON operator-redacted without BARE_OS_PROC_BLIND_PEER_RELAY_HINTS', async (t) => { const a = buildBareOsPearCorestoreHrpcProcJson('blind_relay_router', {}) t.is(a.exposed, false) t.is(a.operatorRedacted, true) const b = buildBareOsPearInspectLoggerTlsProcJson('blind_pairing_sketch', {}) t.is(b.exposed, false) t.is(b.operatorRedacted, true) const c = buildBareOsHypercorePackHrpcLifecycleProcJson('relay_geo_hint', {}) t.is(c.exposed, false) t.is(c.operatorRedacted, true) const { buildBareOsBlindRelaySwarmRuntime } = await import( './lib/bare-os-proc-blind-peer-relay-gate.js' ) const rt = { swarm: buildBareOsBlindRelaySwarmRuntime( { BARE_OS_SWARM_PROTOMUX_BACKPRESSURE_COUNT: '3' }, [{ id: 'a' }, { id: 'b' }], { hasSystemDrive: true, hasPersonalDrive: true, auxiliaryDriveCount: 0 } ) } t.is(rt.swarm.schema, 2) t.is(rt.swarm.replicationSurfaces?.systemDriveOpen, true) const on = buildBareOsPearCorestoreHrpcProcJson( 'blind_relay_router', { BARE_OS_PROC_BLIND_PEER_RELAY_HINTS: '1', BARE_OS_BLIND_RELAY_ROUTER_JSON: '{"lanes":1}', BARE_OS_SWARM_PROTOMUX_BACKPRESSURE_COUNT: '3' }, rt ) t.is(on.schema, 2) t.is(on.exposed, true) t.ok(on.router && typeof on.router === 'object') t.is(on.swarm?.peerCount, 2) t.is(on.swarm?.relayGeoTier, 'multi_peer') t.is(on.swarm?.protomuxBackpressure?.schema, 1) t.is(on.swarm?.protomuxBackpressure?.emitCountEstimate, 3) const pair = buildBareOsPearInspectLoggerTlsProcJson( 'blind_pairing_sketch', { BARE_OS_PROC_BLIND_PEER_RELAY_HINTS: 'yes' }, rt ) t.is(pair.schema, 2) t.is(pair.swarm?.pairingSurfaceReady, true) const geo = buildBareOsHypercorePackHrpcLifecycleProcJson( 'relay_geo_hint', { BARE_OS_PROC_BLIND_PEER_RELAY_HINTS: 'true' }, rt ) t.is(geo.schema, 2) t.ok(geo.regions == null) t.is(geo.swarm?.relayGeoTier, 'multi_peer') }) test('pear_runtime_channel proc JSON surfaces env hints', async (t) => { const j = buildBareOsPearCorestoreHrpcProcJson('pear_runtime_channel', { BARE_OS_PEAR_RUNTIME_CHANNEL: 'dev', BARE_OS_PEAR_RUNTIME_STAGE: '2', BARE_OS_PEAR_INSPECTOR_ATTACH_HINT: 'off', BARE_OS_PEAR_RUNTIME_SNAPSHOT_JSON: '{"schema":1,"ok":true}' }) t.is(j.schema, 1) t.is(j.channel, 'dev') t.is(j.stage, '2') t.is(j.inspectorAttachHint, 'off') t.ok(j.snapshot && typeof j.snapshot === 'object') }) test('protomux_extensions proc JSON gated by BARE_OS_PROC_PROTOMUX_EXTENSIONS_REGISTRY', async (t) => { const off = buildBareOsProtomuxExtensionsProcJson({ env: {} }) t.is(off.exposed, false) const on = buildBareOsProtomuxExtensionsProcJson({ env: { BARE_OS_PROC_PROTOMUX_EXTENSIONS_REGISTRY: '1' }, registrySnapshot: { aliases: {}, schema: 1 }, ctxApiVersion: BARE_OS_CTX_API_VERSION }) t.is(on.exposed, true) t.is(on.schemaVersion, 2) t.is(on.muxWireMajor, 3) t.ok(Array.isArray(on.extensionLogicalChannels)) }) test('buildBareOsReplicationLiveSketch reads hyperdrive core lengths', async (t) => { const dir = testCorestoreDir('replive-sketch') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('rls')) await drive.ready() await personal.ready() const sk0 = buildBareOsReplicationLiveSketch( { drive, personalDrive: personal, auxiliaryDrives: [personal] }, 0 ) t.is(sk0.schema, 2) t.is(sk0.auxiliaryDriveCount, 1) t.is(sk0.stallHint, 'no_peers') t.ok(typeof sk0.systemCoreLength === 'number') const sk1 = buildBareOsReplicationLiveSketch( { drive, personalDrive: personal }, 1 ) t.is(sk1.schema, 2) t.is(sk1.auxiliaryDriveCount, 0) t.is(sk1.stallHint, 'ok') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('protomux_rpc_pool_health proc uses schema 2 and backpressure correlation fields', async (t) => { const j = buildBareOsBareRuntimeProtoMuxProcJson('protomux_rpc_pool_health', { BARE_OS_PROTOMUX_RPC_POOL_HEALTH_JSON: '{"ok":true}', BARE_OS_REPLICATION_BACKPRESSURE_JSON: '{"depth":1}', BARE_OS_LAST_PROTOMUX_BACKPRESSURE_MS: '99' }) t.is(j.schema, 2) t.ok(j.health) t.ok(j.replicationBackpressure) t.is(j.lastProtomuxBackpressureMs, 99) }) test('protomux_rpc_pool_health echoes seed pool hint and wire correlate when env health absent', async (t) => { const j = buildBareOsBareRuntimeProtoMuxProcJson( 'protomux_rpc_pool_health', {}, { seedProtomuxRpcPoolHint: { schema: 1, depth: 2 }, protomuxWireCorrelate: { schema: 1, peerMuxSessions: 3, backpressureEmitCount: 5, aliasPairCount: 1, bareOsV1WireMessageKinds: 7 } } ) t.is(j.schema, 2) t.is(j.health, null) t.is(j.seedProtomuxRpcPoolHintEcho?.depth, 2) t.is(j.protomuxWireCorrelate?.peerMuxSessions, 3) t.is(j.protomuxWireCorrelate?.backpressureEmitCount, 5) }) test('protomux_channels proc includes wireShapeSummary from runtime hints', async (t) => { const j = buildBareOsPearCorestoreHrpcProcJson( 'protomux_channels', {}, { protomuxWireShape: { schema: 1, bareOsV1MessageKinds: ['read', 'rpc_req'], peerMuxSessions: 2 } } ) t.is(j.schema, 1) t.is(j.wireShapeSummary?.peerMuxSessions, 2) t.ok(Array.isArray(j.wireShapeSummary?.bareOsV1MessageKinds)) }) test('pathnameExpandShellWord caps matches with BARE_OS_GLOB_MAX_MATCHES', async (t) => { const names = ['f0', 'f1', 'f2', 'f3', 'f4'] const vfs = { getcwd: () => '/tmp', async readdir(d) { if (d === '/tmp') return names.slice() return [] }, async stat(p) { if (p === '/tmp') return { type: 'directory' } const base = p.replace(/^.*\//, '') if (names.includes(base)) return { type: 'file' } throw new Error('ENOENT') } } const ctx = { vfs } const parts = [{ q: 'u', t: '/tmp/f*' }] const out = await pathnameExpandShellWord(ctx, parts, { BARE_OS_GLOB_MAX_MATCHES: '2' }) t.is(out.length, 2) t.is(out[0], '/tmp/f0') t.is(out[1], '/tmp/f1') }) test('buildBareOsSyscallsProcJson exposes posixLike fd mapping', async (t) => { const j = buildBareOsSyscallsProcJson({ ctxApiVersion: BARE_OS_CTX_API_VERSION }) t.is(j.schemaVersion, 8) t.ok(j.fdModel && j.fdModel.posixLike && j.fdModel.posixLike.pipe) t.ok(j.fdModel.posixLike.read && j.fdModel.posixLike.write) t.ok(j.fdModel.posixLike.fcntl) t.ok(j.fdModel.posixLike.poll) t.ok(j.fdModel.posixLike.socketFamily) t.ok(j.posixXsh && j.posixXsh.schema === 2 && j.posixXsh.namesCsv.includes('open')) t.ok(j.posixXsh.namesCsv.includes('poll')) t.ok(j.posixXsh.namesCsv.includes('select')) t.ok(j.posixXsh.namesCsv.includes('umask')) t.ok(j.posixXsh.namesCsv.includes('readv')) t.ok(j.posixXsh.namesCsv.includes('writev')) t.ok(j.posixXsh.namesCsv.includes('socket')) t.ok(j.posixXsh.namesCsv.includes('sendmsg')) t.ok(j.posixXsh.namesCsv.includes('recvmsg')) t.ok(j.posixXsh.namesCsv.includes('shutdown')) t.is(j.socketMsgSurface?.schema, 3) t.is(j.socketMsgSurface?.ancillaryControl?.supported, false) t.is(j.socketMsgSurface?.ancillaryControl?.errno, 'ENOTSUP') t.ok(Array.isArray(j.socketMsgSurface?.ancillaryControl?.rejectKeys)) const xsh = j.opsDetail.filter((r) => r.posixAlignment) t.ok(xsh.length >= 10) }) test('bareOsParseSendmsgScmRights binary control rejects', async (t) => { const r = bareOsParseSendmsgScmRights( { control: new Uint8Array([1]) }, true, 4 ) t.is(r.ok, false) t.is(/** @type {{ reject: string }} */ (r).reject, 'control') }) test('bareOsParseSendmsgScmRights scm off rejects non-empty fds', async (t) => { const r = bareOsParseSendmsgScmRights({ cmsgs: [{ fds: [3] }] }, false, 4) t.is(r.ok, false) }) test('bareOsParseSendmsgScmRights scm on collects fds', async (t) => { const r = bareOsParseSendmsgScmRights({ cmsgs: [{ fds: [3, 4] }] }, true, 4) t.is(r.ok, true) t.is(/** @type {{ fds: number[] }} */ (r).fds.length, 2) }) test('wantPosixSocketScmRights env', async (t) => { t.absent(wantPosixSocketScmRights({})) t.ok(wantPosixSocketScmRights({ BARE_OS_POSIX_SOCKET_SCM_RIGHTS: '1' })) }) test('maybeBareOsBuildBinManifest writes schema 2 with namesDigest', async (t) => { /** @type {{ path: string, text: string }[]} */ const writes = [] const ctx = { env: { BARE_OS_VFS_BIN_INDEX_BUILD: '1' }, vfs: { writeFile: async (p, buf) => { writes.push({ path: String(p), text: b4a.toString(buf) }) } }, drive: { async *readdir() { yield 'b' yield 'a' } }, b4a, console: {} } await maybeBareOsBuildBinManifest(ctx) t.is(writes.length, 1) t.is(writes[0].path, '/.bare-os/index/bin-manifest.json') const j = JSON.parse(writes[0].text) t.is(j.schema, 2) t.ok(typeof j.namesDigest === 'string' && j.namesDigest.length === 64) t.is(j.names[0], 'a') t.is(j.names[1], 'b') }) test('parseBareOsHrpcAllowlistJson + bareOsHrpcAllowlistDeniesRoute', async (t) => { t.is(parseBareOsHrpcAllowlistJson('').allow, null) t.is(parseBareOsHrpcAllowlistJson(' ').allow, null) const a1 = parseBareOsHrpcAllowlistJson('["kernel.ping"]') t.ok(a1.allow && a1.allow.has('kernel.ping')) t.ok(bareOsHrpcAllowlistDeniesRoute(a1.allow, 'kernel', 'capabilities')) t.absent(bareOsHrpcAllowlistDeniesRoute(a1.allow, 'kernel', 'ping')) const a2 = parseBareOsHrpcAllowlistJson('{"kernel.ping":true}') t.ok(a2.allow && a2.allow.has('kernel.ping')) const a3 = parseBareOsHrpcAllowlistJson('{"*":true}') t.ok(a3.allow && a3.allow.has('*')) t.absent(bareOsHrpcAllowlistDeniesRoute(a3.allow, 'vfs', 'readText')) const a4 = parseBareOsHrpcAllowlistJson('{"kernel.*":true}') t.absent(bareOsHrpcAllowlistDeniesRoute(a4.allow, 'kernel', 'capabilities')) t.ok(bareOsHrpcAllowlistDeniesRoute(a4.allow, 'vfs', 'readText')) t.ok(parseBareOsHrpcAllowlistJson('{').parseError) }) test('pear_doctor_state proc JSON schema 2 parity fields', async (t) => { const j = buildBareOsPearInspectLoggerTlsProcJson( 'pear_doctor_state', { BARE_OS_PEAR_DOCTOR_STATE_JSON: '{"ok":true}', BARE_OS_PEAR_RUNTIME_VERSION: '1.2.3', BARE_OS_PEAR_INSPECT_PROBE: '1', BARE_OS_PEAR_DOCTOR_MODULE: 'pear-doctor' }, {} ) t.is(j.schema, 2) t.is(j.runtimeVersion, '1.2.3') t.is(j.pearInspectProbe, true) t.is(j.pearDoctorModuleHint, 'pear-doctor') t.ok(j.state && typeof j.state === 'object') }) test('split suffix rolls past zz into three-letter names', async (t) => { const a = 'abcdefghijklmnopqrstuvwxyz' function suffix(i) { let idx = i let len = 2 let span = 26 ** len while (idx >= span) { idx -= span len++ span = 26 ** len } let s = '' let n = idx for (let p = 0; p < len; p++) { s = a[n % 26] + s n = Math.floor(n / 26) } return 'x' + s } t.is(suffix(0), 'xaa') t.is(suffix(675), 'xzz') t.is(suffix(676), 'xaaa') t.is(suffix(677), 'xaab') }) test('disk.os replication_snapshot and replication_operator_sketch RPCs', async (t) => { const dir = testCorestoreDir('diskosrpc') const store = new Corestore(dir) const drive = new Hyperdrive(store) await drive.ready() const bridge = createBareOsDiskOsBridge({ drive, bareOsIpc: { list: () => [] }, ctxApiVersion: BARE_OS_CTX_API_VERSION, systemRevision: { currentId: 'cur', pendingId: '', slot: 'a' }, bootStartedMs: Date.now() - 1000, seedReplicationStatus: { depth: 1 } }) const snap = await bridge.execRpc('bare_os', 'replication_snapshot', []) const sj = JSON.parse(snap) t.is(sj.schema, 1) t.is(sj.ok, true) t.ok(typeof sj.writable === 'boolean') const op = await bridge.execRpc('bare_os', 'replication_operator_sketch', []) const oj = JSON.parse(op) t.is(oj.schema, 4) t.is(oj.seedReplicationStatus?.depth, 1) t.is(oj.swarmPeerCount, null) const badIntent = await bridge.execRpc( 'bare_os', 'replication_operator_intent', ['{}'] ) const ij = JSON.parse(badIntent) t.is(ij.ok, false) t.is(ij.code, 'EPERM') await drive.put('/boot/init.js', b4a.from('//x')) const pe = await bridge.execRpc('bare_os', 'path_exists', ['/boot/init.js']) const pej = JSON.parse(pe) t.is(pej.ok, true) t.is(pej.exists, true) const bi = await bridge.execRpc('bare_os', 'boot_init_exists', []) const bij = JSON.parse(bi) t.is(bij.ok, true) t.is(bij.exists, true) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('disk.os searchLocal merges auxiliary drives and disk_os_hints RPC', async (t) => { const dir = testCorestoreDir('diskossearch') const store = new Corestore(dir) const drive = new Hyperdrive(store) const auxStore = store.namespace('auxs') const aux = new Hyperdrive(auxStore) await drive.ready() await aux.ready() await drive.put('/sys/x_only', b4a.from('1')) await aux.put('/mirror/y_aux', b4a.from('2')) const bridge = createBareOsDiskOsBridge({ drive, auxiliaryDrives: [aux], bareOsIpc: { list: () => [] }, ctxApiVersion: BARE_OS_CTX_API_VERSION, systemRevision: null, bootStartedMs: Date.now(), seedMirrorDriveHintV2: { schema: 2, note: 't' }, seedHttpDhtProxyHint: { routes: 1 } }) const m = await bridge.searchLocal('y_aux') t.ok(m.some((p) => p.includes('y_aux'))) const m2 = await bridge.searchLocal('x_only') t.ok(m2.some((p) => p.includes('x_only'))) const h = await bridge.execRpc('bare_os', 'disk_os_hints', []) const hj = JSON.parse(h) t.is(hj.schema, 2) t.is(hj.auxiliaryDriveCount, 1) t.ok(hj.protocolPackageVersion) t.ok(typeof hj.protomuxChannelSchemaVersion === 'number') t.is(hj.mirrorDriveHintV2?.schema, 2) t.is(hj.httpDhtProxyHint?.routes, 1) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ls -l long listing uses session user and regular file mode', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const lsSrc = await readFile(lsPath, 'utf8') const dir = testCorestoreDir('lslong') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pll')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) const lines = [] const ctx = testCtx(drive, personal, { USER: 'carol', UID: '9001', GID: '9001' }) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await ctx.vfs.writeFile('shown.txt', b4a.from('')) await runBinCommand(ctx, ['ls', '-l', 'shown.txt']) const longLine = lines.find((l) => l.includes('shown.txt')) t.ok(longLine) t.ok(longLine.includes('carol')) t.ok(/^-rw/.test(longLine), 'expected regular file mode prefix') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ls --color=always colors directory blue and executable green', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const lsSrc = await readFile(lsPath, 'utf8') const dir = testCorestoreDir('lscolor') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('plsc')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await ctx.vfs.mkdir('subdir', { recursive: true }) await ctx.vfs.writeFile('xfile', b4a.from('')) await ctx.vfs.chmod('xfile', 0o755) await runBinCommand(ctx, ['ls', '--color=always']) const shortLine = lines.find( (l) => l.includes('subdir') && l.includes('xfile') ) t.ok(shortLine) t.ok( /\x1b\[[0-9;]*msubdir\x1b\[0m/.test(shortLine), 'directory uses LS_COLORS di SGR' ) t.ok( /\x1b\[[0-9;]*mxfile\x1b\[0m/.test(shortLine), 'executable uses LS_COLORS ex SGR' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ls honors NO_COLOR over --color=always', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const lsSrc = await readFile(lsPath, 'utf8') const dir = testCorestoreDir('lscolornc') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('plsn')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) const lines = [] const ctx = testCtx(drive, personal, { NO_COLOR: '1' }) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await ctx.vfs.mkdir('onlydir', { recursive: true }) await runBinCommand(ctx, ['ls', '--color=always']) const shortLine = lines.find((l) => l.includes('onlydir')) t.ok(shortLine) t.ok(!shortLine.includes('\x1b['), 'NO_COLOR strips ANSI') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ls rejects unknown long option', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const lsSrc = await readFile(lsPath, 'utf8') const dir = testCorestoreDir('lsbadopt') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('plbo')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) const errs = [] const ctx = testCtx(drive, personal) ctx.console = { log: () => {}, error: (...a) => errs.push(a.join(' ')) } await runBinCommand(ctx, ['ls', '--not-a-real-option']) t.is(ctx.exitCode, 2) t.ok(errs.some((e) => e.includes('unrecognized'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs readFile missing path in home does not throw (touch pattern)', async (t) => { const dir = testCorestoreDir('vfsreadmiss') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvrm')) await sys.ready() await personal.ready() const vfs = createVfs(sys, personal, { HOME: '/home/zed', PWD: '/home/zed', PATH: '/bin', USER: 'zed', UID: '7000', GID: '7000' }) const missing = await vfs.readFile('newfile') t.is(missing, null) await vfs.writeFile('newfile', b4a.from('ok')) t.is(b4a.toString(await vfs.readFile('newfile')), 'ok') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs routes HOME to personal drive', async (t) => { const dir = testCorestoreDir('vfs') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pv')) await sys.ready() await personal.ready() const env = { HOME: '/home/user', PWD: '/home/user', PATH: '/bin' } const vfs = createVfs(sys, personal, env) await vfs.writeFile('f.txt', b4a.from('hi')) const buf = await personal.get(personalHomeBacking('/home/user', 'f.txt')) t.ok(buf) t.is(b4a.toString(buf), 'hi') const sysTry = await sys.get('/home/user/f.txt') t.is(sysTry, null) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs routes /.bare to personal drive', async (t) => { const dir = testCorestoreDir('vfsbare') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvb')) await sys.ready() await personal.ready() await personal.put('/.bare/vault-marker', b4a.from('1')) await sys.put('/.bare/system-only', b4a.from('2')) const env = { HOME: '/home/user', PWD: '/home/user', PATH: '/bin' } const vfs = createVfs(sys, personal, env) const names = await vfs.readdir('/.bare') t.ok(names.includes('vault-marker')) t.is(names.includes('system-only'), false) t.is(await sys.get('/.bare/vault-marker'), null) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs chdir / and stat $HOME root (Hyperdrive rejects entry("/"))', async (t) => { const dir = testCorestoreDir('vfsroot') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pv2')) await sys.ready() await personal.ready() const env = { HOME: '/home/user', PWD: '/home/user', PATH: '/bin' } const vfs = createVfs(sys, personal, env) await vfs.chdir('/') t.is(vfs.getcwd(), '/') const st = await vfs.stat('/home/user') t.is(st.type, 'directory') await vfs.chdir('/home/user') t.is(vfs.getcwd(), '/home/user') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs expands ~ and ~/ to $HOME (not read-only /~)', async (t) => { const dir = testCorestoreDir('vfstilde') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pv3')) await sys.ready() await personal.ready() const env = { HOME: '/home/zuser', PWD: '/home/zuser', PATH: '/bin' } const vfs = createVfs(sys, personal, env) await vfs.chdir('/') await vfs.chdir('~') t.is(vfs.getcwd(), '/home/zuser') await vfs.writeFile('~/tilde.txt', b4a.from('ok')) const buf = await personal.get( personalHomeBacking('/home/zuser', 'tilde.txt') ) t.ok(buf) t.is(b4a.toString(buf), 'ok') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs lists virtual /home at root; /home shows only active session dir', async (t) => { const dir = testCorestoreDir('vfshomevirt') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvh')) await sys.ready() await personal.ready() const envGuest = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin' } const vfsG = createVfs(sys, personal, envGuest) const rootG = await vfsG.readdir('/') t.ok(rootG.includes('home')) t.ok(rootG.includes('bin') || rootG.includes('boot') || rootG.length >= 1) t.alike(await vfsG.readdir('/home'), ['guest']) const envUser = { HOME: '/home/eeb18de988e9', PWD: '/home/eeb18de988e9', PATH: '/bin' } const vfsU = createVfs(sys, personal, envUser) t.alike(await vfsU.readdir('/home'), ['eeb18de988e9']) t.is(await vfsU.stat('/home/guest'), null) await vfsU.writeFile('/home/eeb18de988e9/x', b4a.from('1')) const buf = await personal.get(personalHomeBacking('/home/eeb18de988e9', 'x')) t.ok(buf) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /proc /sys read-only pseudo files; write rejected', async (t) => { const dir = testCorestoreDir('vfsproc') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvproc')) await sys.ready() await personal.ready() const env = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin', USER: 'guest', BARE_OS_CTX_API_VERSION: '9.9.9-test' } const mntMap = new Map() const bareOsIpc = createBareOsIpc() const vfs = createVfs( sys, personal, env, { getMounts: () => mntMap }, { procSnapshot: { version: '1.2.3-test', cmdline: 'unit-test' }, bootStartedMs: Date.now() - 4000, bootProfileText: () => 'mini\n', sessionText: () => 'test-session-id\n', initdRunText: () => 'demo-unit\tactive\t1\tdemo\n', procBareOsSwarmText: () => '{}\n', bareOsIpc } ) const root = await vfs.readdir('/') t.ok(root.includes('proc')) t.ok(root.includes('sys')) t.ok(root.includes('tmp')) t.ok(root.includes('run')) t.ok(root.includes('dev')) t.alike(await vfs.readdir('/proc').then((a) => [...a].sort()), [ 'bare_os', 'bare_os_activity_queue_depth.json', 'bare_os_async_hooks_lag.json', 'bare_os_autobase_writer_hint.json', 'bare_os_autopass_rotation_sketch.json', 'bare_os_autopass_session_sketch.json', 'bare_os_bare_addon_policy.json', 'bare_os_bare_boot_phase_map.json', 'bare_os_bare_crypto_policy.json', 'bare_os_bare_daemon_hooks.json', 'bare_os_bare_diagnostics_channel.json', 'bare_os_bare_inspect_policy.json', 'bare_os_bare_ipc_bridge.json', 'bare_os_bare_kit_bridge.json', 'bare_os_bare_logger_policy.json', 'bare_os_bare_module_resolution.json', 'bare_os_bare_net_interfaces.json', 'bare_os_bare_pack_cache.json', 'bare_os_bare_performance_counters.json', 'bare_os_bare_rpc_registry_sketch.json', 'bare_os_bare_signals_mask.json', 'bare_os_bare_signals_profile.json', 'bare_os_bare_storage_quota.json', 'bare_os_bare_stream_backpressure.json', 'bare_os_bare_thread_pool.json', 'bare_os_bare_timers_budget.json', 'bare_os_bare_timers_histogram.json', 'bare_os_bare_tls_session_hint.json', 'bare_os_bare_vm_sandbox_sketch.json', 'bare_os_bare_worker_pool.json', 'bare_os_bare_ws_gateway_sketch.json', 'bare_os_blind_pairing_sketch.json', 'bare_os_blind_relay_router.json', 'bare_os_boot_graph.json', 'bare_os_bootstrap', 'bare_os_brittle_snapshot_ci.json', 'bare_os_broadcast_encryption_hint.json', 'bare_os_build_attestation_pointer.json', 'bare_os_bundle_preload_hint.json', 'bare_os_capabilities', 'bare_os_capabilities.json', 'bare_os_cellery_sidecar_hint.json', 'bare_os_clock.json', 'bare_os_compact_encoding_profile.json', 'bare_os_corestore_gc_hint.json', 'bare_os_debug.json', 'bare_os_delegate_red.json', 'bare_os_dht_status.json', 'bare_os_dns_map_active.json', 'bare_os_drive_resolve_cache.json', 'bare_os_drive_version_graph.json', 'bare_os_extensions.json', 'bare_os_features', 'bare_os_form_data_delegate_limits.json', 'bare_os_form_data_delegate_limits_v2.json', 'bare_os_giant_phase_program.json', 'bare_os_gip_transport_sketch.json', 'bare_os_git_delegate_stats.json', 'bare_os_git_lfs_budget.json', 'bare_os_git_lfs_pointer_stats.json', 'bare_os_hdms_health.json', 'bare_os_hdms_hints.json', 'bare_os_host_os.json', 'bare_os_hrpc_allowlist_sketch.json', 'bare_os_hrpc_bridge_health.json', 'bare_os_http_dht_proxy_route.json', 'bare_os_hyper_multisig_trust_pointer.json', 'bare_os_hypercore_lengths.json', 'bare_os_hypercore_repair_hint.json', 'bare_os_hypercore_replicate_budget.json', 'bare_os_hypercore_signing_status.json', 'bare_os_hyperdb_readonly_index.json', 'bare_os_hyperdrive_sparse_index.json', 'bare_os_hypermininet_topology.json', 'bare_os_indexer_catchup.json', 'bare_os_initd_dag.json', 'bare_os_initd_graph.json', 'bare_os_ipc_backpressure.json', 'bare_os_kernel_program.json', 'bare_os_libmqjs_queue_depth.json', 'bare_os_locale.json', 'bare_os_manifest_hints', 'bare_os_metrics_live.json', 'bare_os_metrics_prom.json', 'bare_os_multisig_quorum_pointer.json', 'bare_os_net_qos_class.json', 'bare_os_net_summary.json', 'bare_os_oidc_publishing_pointer.json', 'bare_os_pear_api_allowlist_sketch.json', 'bare_os_pear_appling_manifest.json', 'bare_os_pear_build_fingerprint.json', 'bare_os_pear_doctor_state.json', 'bare_os_pear_drop_events.json', 'bare_os_pear_ipc_health.json', 'bare_os_pear_radio_state.json', 'bare_os_pear_rti_pointer.json', 'bare_os_pear_runtime_channel.json', 'bare_os_pear_runtime_matrix.json', 'bare_os_pear_sidecar_bundle_index.json', 'bare_os_pear_stage_pointer.json', 'bare_os_pear_trust.json', 'bare_os_pear_updater_state.json', 'bare_os_pear_user_dirs_map.json', 'bare_os_pear_wakeups_schedule.json', 'bare_os_pear_workshop_flags.json', 'bare_os_peer_health', 'bare_os_protomux_backpressure.json', 'bare_os_protomux_channel_alias_v2.json', 'bare_os_protomux_channels.json', 'bare_os_protomux_extensions.json', 'bare_os_protomux_rpc_pool_health.json', 'bare_os_protomux_wire.json', 'bare_os_provenance', 'bare_os_quotas', 'bare_os_react_native_bare_kit.json', 'bare_os_relay_geo_hint.json', 'bare_os_replication', 'bare_os_replication_backpressure.json', 'bare_os_replication_operator_panel.json', 'bare_os_resources', 'bare_os_rlimits.json', 'bare_os_rocksdb_pointer.json', 'bare_os_safe_sodium_buffer_policy.json', 'bare_os_sandbox_profile.json', 'bare_os_sandbox_worker_queue.json', 'bare_os_security_context.json', 'bare_os_security_posture.json', 'bare_os_seed_handshake', 'bare_os_session_stats', 'bare_os_sidecar_resource_cap.json', 'bare_os_slo_hints.json', 'bare_os_snapshot_hints', 'bare_os_snapshot_hints.json', 'bare_os_staging_slot', 'bare_os_storage_tier_hint.json', 'bare_os_structured_clone_budget_v2.json', 'bare_os_structured_clone_profile.json', 'bare_os_swarm', 'bare_os_sync_window.json', 'bare_os_syscalls', 'bare_os_syscalls.json', 'bare_os_udx_extended.json', 'bare_os_union', 'bare_os_updater_download_state.json', 'bare_os_version', 'bare_os_virtual_registry', 'bare_os_wave11_operator_slo_v2.json', 'bare_os_wave11_peer_qos_sketch.json', 'bare_os_worker_budget.json', 'cpuinfo', 'diskstats', 'loadavg', 'meminfo', 'mounts', 'net', 'self', 'uptime', 'version' ]) t.alike(await vfs.readdir('/proc/self').then((a) => [...a].sort()), [ 'cgroups', 'cmdline', 'environ', 'exe', 'fd', 'limits' ]) const ver = b4a.toString(await vfs.readFile('/proc/version')) t.ok(ver.includes('Bare OS')) t.ok(ver.includes('bare_os_ctx_api_version=1.2.3-test')) const sysVer = b4a.toString(await vfs.readFile('/sys/fs/bare_os/version')) t.ok(sysVer.includes('1.2.3-test')) const cmd = b4a.toString(await vfs.readFile('/proc/self/cmdline')) t.ok(cmd.includes('unit-test')) const mem = b4a.toString(await vfs.readFile('/proc/meminfo')) t.ok(mem.includes('MemTotal:')) const up = b4a.toString(await vfs.readFile('/proc/uptime')) t.ok(/^\d+\.\d+\s+\d+\.\d+/.test(up.trim())) const cpu = b4a.toString(await vfs.readFile('/proc/cpuinfo')) t.ok(cpu.includes('Bare OS pseudo CPU')) const la = b4a.toString(await vfs.readFile('/proc/loadavg')) t.ok(/^\d+\.\d+\s+\d+\.\d+\s+\d+\.\d+\s+/.test(la)) const exe = b4a.toString(await vfs.readFile('/proc/self/exe')) t.ok(exe.includes('pseudo inode')) const cg = b4a.toString(await vfs.readFile('/proc/self/cgroups')) t.ok(cg.includes('bare-os')) t.alike(await vfs.readdir('/proc/net').then((a) => [...a].sort()), [ 'dev', 'tcp', 'udp' ]) const tcp = b4a.toString(await vfs.readFile('/proc/net/tcp')) t.ok(tcp.includes('local_address')) const udp = b4a.toString(await vfs.readFile('/proc/net/udp')) t.ok(udp.includes('sl')) let mountsTxt = b4a.toString(await vfs.readFile('/proc/mounts')) t.ok(mountsTxt.includes('bare-os-root')) t.ok(mountsTxt.includes(' / hyperdrive ')) mntMap.set('vol', { drive: sys, writable: true }) mountsTxt = b4a.toString(await vfs.readFile('/proc/mounts')) t.ok(mountsTxt.includes('/mnt/vol')) t.ok(mountsTxt.includes('bare-os-vol')) t.alike(await vfs.readdir('/dev').then((a) => [...a].sort()), [ 'null', 'shm', 'urandom', 'zero' ]) const ur = await vfs.readFile('/dev/urandom') t.ok(ur && ur.byteLength === 4096) await vfs.writeFile('/dev/null', b4a.from('gone')) t.is((await vfs.readFile('/dev/null'))?.byteLength ?? 0, 0) const z = await vfs.readFile('/dev/zero') t.ok(z && z.byteLength === 65536) t.alike(await vfs.readdir('/run/bare-os').then((a) => [...a].sort()), [ 'boot.json', 'boot_profile', 'ipc', 'ready', 'session', 'unit-journal', 'units', 'virtual' ]) t.alike(await vfs.readdir('/run/bare-os/ipc'), []) bareOsIpc.create('q1') t.alike(await vfs.readdir('/run/bare-os/ipc'), ['q1']) const readP = vfs.readFile('/run/bare-os/ipc/q1') const t0 = Date.now() await vfs.writeFile('/run/bare-os/ipc/q1', b4a.from('ping')) t.is(b4a.toString(await readP), 'ping') t.ok(Date.now() - t0 < 60000, 'kernel ipc ping-pong completes') await vfs.unlink('/run/bare-os/ipc/q1') t.alike(await vfs.readdir('/run/bare-os/ipc'), []) t.is(b4a.toString(await vfs.readFile('/run/bare-os/boot_profile')), 'mini\n') t.is( b4a.toString(await vfs.readFile('/run/bare-os/session')), 'test-session-id\n' ) const units = b4a.toString(await vfs.readFile('/run/bare-os/units')) t.ok(units.includes('demo-unit')) let writeErr = null try { await vfs.writeFile('/proc/version', b4a.from('x')) } catch (e) { writeErr = e } t.ok(writeErr) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /proc/mounts lists mirror aux drives', async (t) => { const dir = testCorestoreDir('vfsauxmount') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvauxm')) const aux = new Hyperdrive(store.namespace('auxmirror')) await sys.ready() await personal.ready() await aux.ready() const env = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin', USER: 'guest' } const vfs = createVfs(sys, personal, env, { getMounts: () => new Map() }, { procBareOsSwarmText: () => '{}\n', getAuxiliaryDrives: () => [aux], getAuxiliaryMountLines: () => [ 'bare-os-aux0 /mirror/aux0 hyperdrive ro 0 0' ] }) const mountsTxt = b4a.toString(await vfs.readFile('/proc/mounts')) t.ok(mountsTxt.includes('bare-os-aux0')) t.ok(mountsTxt.includes('/mirror/aux0')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs BARE_OS_HIDE_PROC_HYPERCORE_PACK_HRPC_LIFECYCLE=0 hides wave11 proc nodes', async (t) => { const dir = testCorestoreDir('vfsprocw11') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvprocw11')) await sys.ready() await personal.ready() const env = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin', USER: 'guest', BARE_OS_HIDE_PROC_HYPERCORE_PACK_HRPC_LIFECYCLE: '0' } const mntMap = new Map() const vfs = createVfs(sys, personal, env, { getMounts: () => mntMap }, { procBareOsSwarmText: () => '{}\n' }) const flatW11 = Object.keys(BARE_OS_PROC_FILE_TO_ID_HYPERCORE_PACK_HRPC_LIFECYCLE).map((k) => k.endsWith('.json') ? k : `${k}.json` ) const bareOsW11 = Object.keys(BARE_OS_PROC_FILE_TO_ID_HYPERCORE_PACK_HRPC_LIFECYCLE).map((k) => { const base = k.startsWith('bare_os_') ? k.slice('bare_os_'.length) : k return base.endsWith('.json') ? base : `${base}.json` }) const procRoot = await vfs.readdir('/proc').then((a) => [...a]) for (const n of flatW11) { t.ok(!procRoot.includes(n), `flat ${n} should be hidden`) } const bo = await vfs.readdir('/proc/bare_os').then((a) => [...a]) for (const n of bareOsW11) { t.ok(!bo.includes(n), `bare_os/${n} should be hidden`) } t.is( await vfs.readFile('/proc/bare_os_hypercore_replicate_budget.json'), null ) const idxRaw = b4a.toString(await vfs.readFile('/proc/bare_os/index.json')) const idx = JSON.parse(idxRaw) t.ok(Array.isArray(idx.entries)) const names = new Set(idx.entries.map((e) => e.name)) t.ok(!names.has('hypercore_replicate_budget.json')) t.ok(!names.has('wave11_peer_qos_sketch.json')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /proc/self/environ omits secret-like env keys', async (t) => { const dir = testCorestoreDir('vfsprocenv') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvpe')) await sys.ready() await personal.ready() const env = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin', USER: 'guest', MY_PASSWORD: 'hunter2', BARE_OS_SAFE: 'visible' } const vfs = createVfs(sys, personal, env) const raw = b4a.toString(await vfs.readFile('/proc/self/environ')) t.ok(raw.includes('HOME=')) t.ok(raw.includes('BARE_OS_SAFE=')) t.ok(!raw.includes('MY_PASSWORD')) t.ok(!raw.includes('hunter2')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /tmp maps to personal drive per HOME basename', async (t) => { const dir = testCorestoreDir('vfstmp') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvtmp')) await sys.ready() await personal.ready() const vfsGuest = createVfs(sys, personal, { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin' }) await vfsGuest.writeFile('/tmp/session.dat', b4a.from('g')) t.is(b4a.toString(await personal.get('/.bare-os/tmp/guest/session.dat')), 'g') const vfsUser = createVfs(sys, personal, { HOME: '/home/hexuserdead', PWD: '/home/hexuserdead', PATH: '/bin' }) t.is(await vfsUser.readFile('/tmp/session.dat'), null) await vfsUser.writeFile('/tmp/session.dat', b4a.from('u')) t.is( b4a.toString(await personal.get('/.bare-os/tmp/hexuserdead/session.dat')), 'u' ) t.is(b4a.toString(await personal.get('/.bare-os/tmp/guest/session.dat')), 'g') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs isolates home and /var/log per HOME basename on personal drive', async (t) => { const dir = testCorestoreDir('vfsisol') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvis')) await sys.ready() await personal.ready() const vfsGuest = createVfs(sys, personal, { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin' }) await vfsGuest.writeFile('shared-name.txt', b4a.from('guest-data')) await vfsGuest.writeFile('/var/log/bare-os/g.log', b4a.from('glog')) const vfsUser = createVfs(sys, personal, { HOME: '/home/alice12hex', PWD: '/home/alice12hex', PATH: '/bin' }) t.is(await vfsUser.readFile('/home/alice12hex/shared-name.txt'), null) await vfsUser.writeFile('shared-name.txt', b4a.from('user-data')) t.is( b4a.toString( await personal.get(personalHomeBacking('/home/guest', 'shared-name.txt')) ), 'guest-data' ) t.is( b4a.toString( await personal.get( personalHomeBacking('/home/alice12hex', 'shared-name.txt') ) ), 'user-data' ) t.is( b4a.toString(await personal.get('/.bare-os/var/log/guest/bare-os/g.log')), 'glog' ) await vfsUser.writeFile('/var/log/bare-os/u.log', b4a.from('ulog')) t.is( b4a.toString( await personal.get('/.bare-os/var/log/alice12hex/bare-os/u.log') ), 'ulog' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('guest VFS denies sensitive /.bare paths; unlocked allows', async (t) => { const dir = testCorestoreDir('vfsbarepol') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvpol')) await sys.ready() await personal.ready() await personal.put('/.bare/account', b4a.from('acctblob')) await personal.put('/.bare/vault/x', b4a.from('v')) const envG = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin' } const vfsG = createVfs(sys, personal, envG) vfsG.bareOsIdentitySession = 'guest' t.is(await vfsG.exists('/.bare/account'), false) await t.exception(async () => { await vfsG.readFile('/.bare/account') }) const envU = { HOME: '/home/abc123deadbe', PWD: '/home/abc123deadbe', PATH: '/bin', UID: '999', USER: 'abc123deadbe' } const vfsU = createVfs(sys, personal, envU) vfsU.bareOsIdentitySession = 'unlocked' t.is(b4a.toString(await vfsU.readFile('/.bare/account')), 'acctblob') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('BARE_OS_PERSONAL_ACCT_PREFIX nests guest tmp on personal drive', async (t) => { const dir = testCorestoreDir('vfsacct') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvacct')) await sys.ready() await personal.ready() const env = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin', BARE_OS_PERSONAL_ACCT_PREFIX: '1' } const vfs = createVfs(sys, personal, env) await vfs.writeFile('/tmp/acct.txt', b4a.from('ok')) t.is( b4a.toString(await personal.get('/.bare-os/acct/_guest/tmp/guest/acct.txt')), 'ok' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /mnt lists HDMS mounts and allows writable put', async (t) => { const dir = testCorestoreDir('vfsmnt') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvm')) await sys.ready() await personal.ready() const env = { HOME: '/home/u', PWD: '/home/u', PATH: '/bin' } const extra = new Hyperdrive(store.namespace('exm', { writable: true })) await extra.ready() const mntRef = { getMounts: () => new Map([['vault', { drive: extra, writable: true }]]) } const vfs = createVfs(sys, personal, env, mntRef) const root = await vfs.readdir('/') t.ok(root.includes('mnt')) t.alike(await vfs.readdir('/mnt'), ['vault']) await vfs.writeFile('/mnt/vault/x.txt', b4a.from('ok')) const buf = await extra.get('/x.txt') t.ok(buf) t.is(b4a.toString(buf), 'ok') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs /var in root readdir; /var/log empty lstat; writes map to personal', async (t) => { const dir = testCorestoreDir('vfsvar') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvvar')) await sys.ready() await personal.ready() const env = { HOME: '/home/u', PWD: '/home/u', PATH: '/bin' } const vfs = createVfs(sys, personal, env) const root = await vfs.readdir('/') t.ok(root.includes('var')) t.alike(await vfs.readdir('/var'), ['log']) const stLog = await vfs.lstat('/var/log') t.ok(stLog) t.is(stLog.type, 'directory') await vfs.mkdir('/var/log/bare-os', { recursive: true }) await vfs.writeFile('/var/log/bare-os/test-vfs.log', b4a.from('hello')) const buf = await personal.get('/.bare-os/var/log/u/bare-os/test-vfs.log') t.ok(buf) t.is(b4a.toString(buf), 'hello') const sysTry = await sys.get('/.bare-os/var/log/u/bare-os/test-vfs.log') t.is(sysTry, null) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs chdir /var/log from home', async (t) => { const dir = testCorestoreDir('vfsvarcd') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvcv')) await sys.ready() await personal.ready() const vfs = createVfs(sys, personal, { HOME: '/home/u', PWD: '/home/u', PATH: '/bin' }) await vfs.chdir('/var/log') t.is(vfs.getcwd(), '/var/log') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tokenize handles quotes and ops', async (t) => { const tok = tokenize('ls -la | cat > out') t.ok(tok.some((x) => x.type === 'op' && x.value === '|')) t.ok(tok.some((x) => x.type === 'op' && x.value === '>')) const w = tokenize("echo 'a b'") const words = w.filter((x) => x.type === 'word').map((x) => x.value) t.is(words.join(','), 'echo,a b') }) test('tokenize records quote parts for glob (literal * in quotes)', async (t) => { const u = tokenize('echo *') const uwords = u.filter((x) => x.type === 'word') const star = uwords[uwords.length - 1] t.ok(star && star.type === 'word' && star.parts) t.is(star.parts.length, 1) t.is(star.parts[0].q, 'u') t.is(star.parts[0].t, '*') const sq = tokenize("echo '*'") const sqw = sq.filter((x) => x.type === 'word') t.is(sqw[0].value, 'echo') const lit = sqw[1] t.is(lit.parts.length, 1) t.is(lit.parts[0].q, 's') t.is(lit.parts[0].t, '*') }) test('execShellLine pathname glob and noglob', async (t) => { const dir = testCorestoreDir('shglob') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('sglob')) await drive.ready() await personal.ready() const echo = ` async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) } ` await drive.put('/bin/echo', b4a.from(echo)) const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('/home/user/a.txt', b4a.from('x')) await ctx.vfs.writeFile('/home/user/b.txt', b4a.from('y')) const logs = [] ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } await ctx.vfs.chdir('/home/user') await execShellLine(ctx, 'echo *.txt') t.ok( logs.some((l) => l.includes('a.txt') && l.includes('b.txt')), logs.join('|') ) logs.length = 0 await execShellLine(ctx, "echo '*.txt'") t.ok(logs.some((l) => l === '*.txt'), logs.join('|')) logs.length = 0 ctx.vfs.env.BARE_OS_SHELL_NOGLOB = '1' await execShellLine(ctx, 'echo *.txt') t.ok(logs.some((l) => l === '*.txt')) delete ctx.vfs.env.BARE_OS_SHELL_NOGLOB await execShellLine(ctx, 'set -f; echo *.txt') t.ok(logs.some((l) => l === '*.txt')) await execShellLine(ctx, 'set +f; echo *.txt') t.ok(logs.some((l) => l.includes('a.txt'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine BARE_OS_SHELL_POSIX_MODE grouped list', async (t) => { const dir = testCorestoreDir('shposixgroup') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('spg')) await drive.ready() await personal.ready() const echo = ` async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) } ` await drive.put('/bin/echo', b4a.from(echo)) const ctx = testCtx(drive, personal) const logs = [] ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } ctx.vfs.env.BARE_OS_SHELL_POSIX_MODE = '1' await ctx.vfs.chdir('/home/user') await execShellLine(ctx, '( echo hi )') t.ok(logs.some((l) => l === 'hi')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('expandWord reads env', async (t) => { t.is(expandWord('x${HOME}y', { HOME: '/h' }), 'x/hy') }) test('expandWord $? and ${?} use BARE_OS_EXIT_STATUS', async (t) => { const env = { [BARE_OS_EXIT_STATUS_ENV]: '7', HOME: '/h' } t.is(expandWord('code=$?', env), 'code=7') t.is(expandWord('c=${?}', env), 'c=7') t.is(expandWord('missing=$?', {}), 'missing=0') }) test('expandWord param expansion v2 (## %% :=)', async (t) => { const base = { BARE_OS_SHELL_PARAM_EXPANSION: '1', BARE_OS_SHELL_PARAM_EXPANSION_V2: '1', P: '/usr/bin/foo', Q: 'caba' } t.is(expandWord('${P##*/}', base), 'foo') t.is(expandWord('${P#*/}', base), 'usr/bin/foo') t.is(expandWord('${Q%%ba}', base), 'ca') t.is(expandWord('${Q%ba}', base), 'ca') const assign = { ...base, EMPTY: '' } t.is(expandWord('${EMPTY:=set}', assign), 'set') t.is(assign.EMPTY, 'set') }) /** POSIX-style parameter expansion vectors (Issue 7 subset; env-gated V3). */ test('expandWord param expansion v3 (:- :+ :?)', async (t) => { const base = { BARE_OS_SHELL_PARAM_EXPANSION: '1', BARE_OS_SHELL_PARAM_EXPANSION_V3: '1', HOME: '/home/u' } t.is(expandWord('${UNSET:-/default}', base), '/default') t.is(expandWord('${EMPTY:-/alt}', { ...base, EMPTY: '' }), '/alt') t.is(expandWord('${SET:-ignored}', { ...base, SET: 'ok' }), 'ok') t.is(expandWord('${SET:+present}', { ...base, SET: 'v' }), 'present') t.is(expandWord('${UNSET:+absent}', base), '') t.exception( () => expandWord('${UNSET:?hard fail}', base), /hard fail|parameter null or unset/ ) t.exception( () => expandWord('${EMPTY:?msg}', { ...base, EMPTY: '' }), /msg|parameter null or unset/ ) }) test('syncBareOsExitStatusEnv and execShellLine update env', async (t) => { const dir = testCorestoreDir('exstat') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pex')) await drive.ready() await personal.ready() await drive.put( '/bin/false', b4a.from(`async function run(ctx) { ctx.exitCode = 1 }`) ) await drive.put( '/bin/true', b4a.from(`async function run(ctx) { ctx.exitCode = 0 }`) ) const ctx = testCtx(drive, personal) ctx.exitCode = 0 syncBareOsExitStatusEnv(ctx) t.is(ctx.vfs.env[BARE_OS_EXIT_STATUS_ENV], '0') await execShellLine(ctx, 'false') t.is(ctx.vfs.env[BARE_OS_EXIT_STATUS_ENV], '1') await execShellLine(ctx, 'true') t.is(ctx.vfs.env[BARE_OS_EXIT_STATUS_ENV], '0') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine BARE_OS_SHELL_ERREXIT skips after failed command', async (t) => { const dir = testCorestoreDir('errexit') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pex-e')) await drive.ready() await personal.ready() await drive.put( '/bin/false', b4a.from(`async function run(ctx) { ctx.exitCode = 1 }`) ) await drive.put( '/bin/true', b4a.from(`async function run(ctx) { ctx.exitCode = 0 }`) ) await drive.put( '/bin/echo', b4a.from( `async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) }` ) ) const logs = [] const ctx = testCtx(drive, personal) ctx.console = { log: (m) => logs.push(String(m)), error: (...a) => logs.push(a.map(String).join(' ')) } ctx.vfs.env.BARE_OS_SHELL_ERREXIT = '1' await execShellLine(ctx, 'false; echo AFTER') t.ok(!logs.some((l) => l.includes('AFTER'))) logs.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'true; echo OK') t.ok(logs.some((l) => l.includes('OK'))) logs.length = 0 ctx.exitCode = 0 delete ctx.vfs.env.BARE_OS_SHELL_ERREXIT await execShellLine(ctx, 'set -e; false; echo NEVER') t.ok(!logs.some((l) => l.includes('NEVER'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine errexit stops inside if-then body after failure', async (t) => { const dir = testCorestoreDir('errexit-if') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pex-eif')) await drive.ready() await personal.ready() await drive.put( '/bin/false', b4a.from(`async function run(ctx) { ctx.exitCode = 1 }`) ) await drive.put( '/bin/echo', b4a.from( `async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) }` ) ) const logs = [] const ctx = testCtx(drive, personal) ctx.console = { log: (m) => logs.push(String(m)), error: (...a) => logs.push(a.map(String).join(' ')) } ctx.vfs.env.BARE_OS_SHELL_ERREXIT = '1' await execShellLine(ctx, 'if true; then false; echo BAD; fi') t.ok(!logs.some((l) => l.includes('BAD'))) logs.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'if false; then echo no; fi; echo AFTER') t.ok(logs.some((l) => l.includes('AFTER'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('evaluateBareOsPeerAdmission honors dhtAddressClass with allowlist', async (t) => { const env = { BARE_OS_PEER_ALLOWLIST_HEX: '', BARE_OS_DHT_ADDRESS_CLASS_ALLOWLIST: 'ipv4,relay' } const deny = evaluateBareOsPeerAdmission(env, 'aa', { dhtAddressClass: 'ipv6' }) t.is(deny.verdict, 'deny') const ok = evaluateBareOsPeerAdmission(env, 'aa', { dhtAddressClass: 'ipv4' }) t.is(ok.verdict, 'allow') }) test('BARE_OS_CTX_API_VERSION is semver-shaped', async (t) => { t.ok(/^\d+\.\d+\.\d+$/.test(BARE_OS_CTX_API_VERSION)) }) test('getBareOsPipelineLimits reads BARE_OS_PIPELINE_* from env', async (t) => { const def = getBareOsPipelineLimits({}) t.is(def.maxStages, DEFAULT_PIPELINE_MAX_STAGES) const custom = getBareOsPipelineLimits({ BARE_OS_PIPELINE_MAX_STAGES: '4', BARE_OS_PIPELINE_MAX_BYTES: '100', BARE_OS_PIPELINE_MAX_LINES: '20' }) t.is(custom.maxStages, 4) t.is(custom.maxBytes, 100) t.is(custom.maxLines, 20) }) test('buildBareOsRuntimeCaps matches ctx API version and pipeline env', async (t) => { const caps = buildBareOsRuntimeCaps({ BARE_OS_PIPELINE_MAX_STAGES: '8', BARE_OS_CTX_API_VERSION }) t.is(caps.ctxApiVersion, BARE_OS_CTX_API_VERSION) t.is(caps.pipeline.maxStages, 8) t.ok(Array.isArray(caps.pseudoFsPaths)) t.ok(caps.pseudoFsPaths.includes('/proc/version')) t.ok(caps.pseudoFsPaths.includes('/run/bare-os/boot_profile')) t.ok(caps.pseudoFsPaths.includes('/run/bare-os/ipc')) t.ok(caps.pseudoFsPaths.includes('/run/bare-os/session')) t.ok(caps.pseudoFsPaths.includes('/proc/mounts')) t.ok(caps.pseudoFsPaths.includes('/proc/bare_os_resources')) t.ok(caps.pseudoFsPaths.includes('/run/bare-os/virtual')) t.ok(caps.pseudoFsPaths.includes('/run/bare-os/unit-journal')) t.ok(caps.pseudoFsPaths.includes('/snapshots')) t.ok(caps.pseudoFsPaths.includes('/snapshots/system')) t.is(caps.features.simulatedPipelines, true) t.is(caps.features.httpDelegate, true) t.is(caps.features.gitDelegate, true) t.is(caps.features.systemctlDelegate, true) t.is(caps.features.bareCtxModules, true) t.is(caps.features.bareDriveBundles, true) t.is(caps.features.bareHostImportsForCtx, true) const capsOff = buildBareOsRuntimeCaps({ BARE_OS_BARE_MODULES: '0' }) t.is(capsOff.features.bareCtxModules, false) t.is(capsOff.features.bareDriveBundles, false) t.is(capsOff.features.bareHostImportsForCtx, false) const capsIso = buildBareOsRuntimeCaps({ BARE_OS_BARE_HOST_IMPORTS: '0' }) t.is(capsIso.features.bareHostImportsForCtx, false) t.is(capsIso.features.bareCtxModules, true) }) test('bareOsBareModulesEnabled respects BARE_OS_BARE_MODULES', async (t) => { t.ok(bareOsBareModulesEnabled({})) t.ok(!bareOsBareModulesEnabled({ BARE_OS_BARE_MODULES: '0' })) t.ok(!bareOsBareModulesEnabled({ BARE_OS_BARE_MODULES: 'false' })) }) test('loadBareModuleManifest has entries', async (t) => { const m = loadBareModuleManifest() t.ok(m.version >= 1) t.ok(Array.isArray(m.entries)) t.ok(m.entries.some((e) => e.ctxKey === 'b4a')) }) function stableStringifyManifest(obj) { if (obj === null || typeof obj !== 'object') return JSON.stringify(obj) if (Array.isArray(obj)) { return '[' + obj.map((x) => stableStringifyManifest(x)).join(',') + ']' } const keys = Object.keys(obj).sort() return ( '{' + keys .map((k) => JSON.stringify(k) + ':' + stableStringifyManifest(obj[k])) .join(',') + '}' ) } test('bare-module-manifest.data.mjs matches bare-module-manifest.json', async (t) => { const dir = path.dirname(fileURLToPath(import.meta.url)) const jsonPath = path.join(dir, 'lib', 'bare-module-manifest.json') const fromJson = JSON.parse(await readFile(jsonPath, 'utf8')) const embedded = bareOsBareModuleManifestEmbeddedRef() t.is(stableStringifyManifest(fromJson), stableStringifyManifest(embedded)) }) test('buildBareCtxObjectFromHost loads core keys on Node', async (t) => { const target = {} await buildBareCtxObjectFromHost({}, target) t.ok(target.b4a) t.ok(target.compactEncoding) t.ok(target.protomux) }) test('maybeMergeBareFromDrive fills missing keys from bundle (mock vfs)', async (t) => { const repoRoot = path.join( fileURLToPath(new URL('.', import.meta.url)), '..', '..' ) const bundleAbs = path.join(repoRoot, 'kernel/lib/bare/bundles/b4a.js') const bundleSrc = await readFile(bundleAbs) const manifest = { version: 1, bundles: [{ path: '/lib/bare/bundles/b4a.js', keys: ['b4a'] }] } const target = {} const vfs = { async readFile(p) { if (p === '/lib/bare/manifest.json') return b4a.from(JSON.stringify(manifest)) if (p === '/lib/bare/bundles/b4a.js') return new Uint8Array(bundleSrc) return null } } await maybeMergeBareFromDrive({}, vfs, target) t.ok(target.b4a) }) test('expandArgvAliases expands first word and keeps trailing argv', async (t) => { t.alike(expandArgvAliases(['ll', 'z'], defaultShellAliases()), [ 'ls', '-la', 'z' ]) }) test('expandArgvAliases leaves sed unchanged', async (t) => { t.alike( expandArgvAliases(['sed', 's/a/b/', 'x.txt'], defaultShellAliases()), ['sed', 's/a/b/', 'x.txt'] ) }) test('defaultShellAliases does not remap sed', async (t) => { t.is(defaultShellAliases().sed, undefined) }) test('defaultShellAliases top maps to baretop', async (t) => { t.is(defaultShellAliases().top, 'baretop') }) test('defaultShellAliases btop maps to baretop', async (t) => { t.is(defaultShellAliases().btop, 'baretop') }) test('defaultShellAliases nano maps to edit', async (t) => { t.is(defaultShellAliases().nano, 'edit') t.alike(expandArgvAliases(['nano', 'x'], defaultShellAliases()), [ 'edit', 'x' ]) }) test('expandArgvAliases throws on cyclic alias chain', async (t) => { const cyclic = { a: 'b', b: 'a' } t.exception( () => expandArgvAliases(['a'], cyclic), /alias: expansion nested too deeply/ ) }) test('loadBarerc applies export and alias from personal ~/.barerc', async (t) => { const dir = testCorestoreDir('barerc') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('brc')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', '.barerc'), b4a.from('export MYRC=1\nalias dog=echo woof\n') ) const ctx = testCtx(drive, personal) await loadBarerc(ctx) t.is(ctx.vfs.env.MYRC, '1') t.is(ctx.shellAliases.dog, 'echo woof') t.is(ctx.shellAliases.ll, 'ls -la') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('loadBarerc createSkeletonIfMissing writes ~/.barerc when absent', async (t) => { const dir = testCorestoreDir('barercskel') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('brcsk')) await drive.ready() await personal.ready() const ctx = testCtx(drive, personal) await loadBarerc(ctx, { createSkeletonIfMissing: true }) const back = await ctx.vfs.readFile('~/.barerc') t.ok(back) t.is(ctx.b4a.toString(back), BARERC_SKELETON) t.is(ctx.shellAliases.ll, 'ls -la') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('loadBarerc theme nord sets REPL color env and LS_COLORS', async (t) => { const dir = testCorestoreDir('barerctheme') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('brcth')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', '.barerc'), b4a.from('theme nord\n') ) const ctx = testCtx(drive, personal) await loadBarerc(ctx) t.is(ctx.vfs.env.BARE_OS_THEME, 'nord') t.ok( String(ctx.vfs.env.BARE_OS_COLOR_PROMPT || '').includes('38;2;'), 'nord preset uses truecolor prompt' ) t.ok( String(ctx.vfs.env.LS_COLORS || '').includes('di='), 'LS_COLORS set from preset' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine barerc reload reapplies barerc', async (t) => { const dir = testCorestoreDir('barercrel') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('brcrel')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', '.barerc'), b4a.from('export MARK=before\n') ) const ctx = testCtx(drive, personal) await loadBarerc(ctx) t.is(ctx.vfs.env.MARK, 'before') await personal.put( personalHomeBacking('/home/user', '.barerc'), b4a.from('export MARK=after\n') ) await execShellLine(ctx, 'barerc reload') t.is(ctx.vfs.env.MARK, 'after') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('bareParseLsColors roundtrip', async (t) => { const s = 'di=01;34:ln=36:ex=32:*.tar=01;31' const m = bareParseLsColors(s) t.is(m.di, '01;34') t.is(m.ln, '36') t.alike(bareParseLsColors(bareSerializeLsColors(m)), m) }) test('bareLsColorOpenSgrFromMap directory and glob', async (t) => { const map = bareParseLsColors('di=01;34:*.md=00;32') const d = bareLsColorOpenSgrFromMap( { type: 'directory', mode: 0o040755 }, 'foo', map ) t.ok(d.startsWith('\x1b['), 'directory colored') const md = bareLsColorOpenSgrFromMap( { type: 'file', mode: 0o100644 }, 'README.md', map ) t.ok(md.includes('32'), 'markdown glob') }) test('bareLsColorOpenSgrFromMap mh for multi-link regular file', async (t) => { const map = bareParseLsColors('mh=01;44:fi=40;31') const one = bareLsColorOpenSgrFromMap( { type: 'file', mode: 0o100644, nlink: 1 }, 'a', map ) const two = bareLsColorOpenSgrFromMap( { type: 'file', mode: 0o100644, nlink: 2 }, 'a', map ) t.ok(two.includes('44'), 'nlink>1 uses mh SGR') t.ok(one.includes('31'), 'nlink 1 uses fi') }) test('bareLsColorOpenSgrFromMap ca when stat has capabilities', async (t) => { const map = bareParseLsColors('ca=30;41:fi=00') const sgr = bareLsColorOpenSgrFromMap( { type: 'file', mode: 0o100644, nlink: 1, capabilities: true }, 'cap', map ) t.ok(sgr.includes('41'), 'capabilities use ca') }) test('applyBareOsThemeFromEnv BARE_OS_COLOR_DEPTH=256 drops truecolor', async (t) => { const ctx = { vfs: { env: { BARE_OS_THEME: 'nord', BARE_OS_COLOR_DEPTH: '256' } } } await applyBareOsThemeFromEnv(ctx) const p = String(ctx.vfs.env.BARE_OS_COLOR_PROMPT || '') t.ok(p.includes('38;5;'), '256-color palette index SGR') t.ok(!p.includes('38;2;'), 'no RGB truecolor') }) test('dircolors -p includes TERM and di', async (t) => { const db = bareDefaultDircolorsDatabase() t.ok(db.includes('TERM')) t.ok(db.includes('di ')) }) test('bareParseDircolorsDatabase TERM block', async (t) => { const text = 'TERM xterm\ndi 01;34\nTERM none\nfi 00\nTERM *\nln 01;36\n' const m = bareParseDircolorsDatabase(text, 'xterm') t.is(m.di, '01;34') t.is(m.ln, '01;36') }) test('runBinCommand theme set writes barerc and updates env', async (t) => { const themePath = path.join(__dirname, '../../kernel/bin/theme') const themeSrc = await readFile(themePath, 'utf8') const dir = testCorestoreDir('themecmd') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('thcmd')) await drive.ready() await personal.ready() await drive.put('/bin/theme', b4a.from(themeSrc)) const ctx = testCtx(drive, personal) await loadBarerc(ctx) await runBinCommand(ctx, ['theme', 'set', 'dracula']) t.is(ctx.vfs.env.BARE_OS_THEME, 'dracula') const barc = ctx.b4a.toString(await ctx.vfs.readFile('~/.barerc')) t.ok(barc.includes('theme dracula')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand dircolors -p prints database', async (t) => { const dcPath = path.join(__dirname, '../../kernel/bin/dircolors') const dcSrc = await readFile(dcPath, 'utf8') const dir = testCorestoreDir('dircolp') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('dcp')) await drive.ready() await personal.ready() await drive.put('/bin/dircolors', b4a.from(dcSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await runBinCommand(ctx, ['dircolors', '-p']) const out = lines.join('\n') t.ok(out.includes('TERM')) t.ok(out.includes('di')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand edit --help prints usage', async (t) => { const editPath = path.join(__dirname, '../../kernel/bin/edit') const editSrc = await readFile(editPath, 'utf8') const dir = testCorestoreDir('edithlp') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('edh')) await drive.ready() await personal.ready() await drive.put('/bin/edit', b4a.from(editSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await runBinCommand(ctx, ['edit', '--help']) const out = lines.join('\n') t.ok(out.includes('usage:')) t.ok(out.includes('TTY')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand edit requires TTY', async (t) => { const editPath = path.join(__dirname, '../../kernel/bin/edit') const editSrc = await readFile(editPath, 'utf8') const dir = testCorestoreDir('ednotty') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('ednt')) await drive.ready() await personal.ready() await drive.put('/bin/edit', b4a.from(editSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.replStdin = { isTTY: false } ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await runBinCommand(ctx, ['edit', 'x.txt']) t.is(ctx.exitCode, 1) t.ok(lines.some((l) => l.includes('TTY'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand baretop --help prints usage', async (t) => { const binPath = path.join(__dirname, '../../kernel/bin/baretop') const src = await readFile(binPath, 'utf8') const dir = testCorestoreDir('baretophlp') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('bth')) await drive.ready() await personal.ready() await drive.put('/bin/baretop', b4a.from(src)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await runBinCommand(ctx, ['baretop', '--help']) const out = lines.join('\n') t.ok(out.includes('usage:')) t.ok(out.includes('TTY')) t.ok(out.toLowerCase().includes('dashboard')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand baretop requires TTY', async (t) => { const binPath = path.join(__dirname, '../../kernel/bin/baretop') const src = await readFile(binPath, 'utf8') const dir = testCorestoreDir('baretopntty') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('btnt')) await drive.ready() await personal.ready() await drive.put('/bin/baretop', b4a.from(src)) const lines = [] const ctx = testCtx(drive, personal) ctx.replStdin = { isTTY: false } ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await runBinCommand(ctx, ['baretop']) t.is(ctx.exitCode, 1) t.ok(lines.some((l) => l.includes('TTY'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand nano --help matches edit bundle', async (t) => { const nanoPath = path.join(__dirname, '../../kernel/bin/nano') const nanoSrc = await readFile(nanoPath, 'utf8') const dir = testCorestoreDir('nanohlp') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('nanh')) await drive.ready() await personal.ready() await drive.put('/bin/nano', b4a.from(nanoSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await runBinCommand(ctx, ['nano', '-h']) const out = lines.join('\n') t.ok(out.includes('usage:')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tokenize leaves echo 2 > file as stdout redirect not 2>', async (t) => { const toks = tokenize('echo 2 > /tmp/x') const words = toks.filter((x) => x.type === 'word').map((x) => x.value) t.ok(words.includes('2')) t.ok(toks.some((x) => x.type === 'op' && x.value === '>')) t.ok(!toks.some((x) => x.type === 'op' && x.value === '2>')) }) test('execShellLine stderr 2> and 2>&1 in pipeline', async (t) => { const dir = testCorestoreDir('sherr') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('serr')) await drive.ready() await personal.ready() const emit = ` async function run(ctx) { ctx.console.log('OUT') ctx.console.error('ERR') } ` const cat = ` function bareStdin(ctx) { return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : '' } async function run(ctx) { ctx.console.log(bareStdin(ctx).replace(/\\n$/, '')) } ` await drive.put('/bin/emit', b4a.from(emit)) await drive.put('/bin/cat', b4a.from(cat)) const ctx = testCtx(drive, personal) await execShellLine(ctx, 'emit 2>~/e.out') const eb = await ctx.vfs.readFile('~/e.out') t.ok(eb && ctx.b4a.toString(eb).includes('ERR')) t.ok(!ctx.b4a.toString(eb).includes('OUT')) await ctx.vfs.unlink('~/e.out') const logs = [] ctx.console = { log: (...a) => logs.push(['out', ...a]), error: (...a) => logs.push(['err', ...a]) } await execShellLine(ctx, 'emit 2>&1 | cat') const piped = logs .filter((x) => x[0] === 'out') .map((x) => x.slice(1).join(' ')) t.ok(piped.some((l) => l.includes('OUT') && l.includes('ERR'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine pipeline < in and > out redirection', async (t) => { const dir = testCorestoreDir('shpipeio') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('spio')) await drive.ready() await personal.ready() const cat = ` function bareStdin(ctx) { return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : '' } async function run(ctx) { ctx.console.log(bareStdin(ctx).replace(/\\n$/, '')) } ` await drive.put('/bin/cat', b4a.from(cat)) const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('~/in.txt', b4a.from('pipeline-data\n')) await execShellLine(ctx, 'cat < ~/in.txt | cat > ~/out.txt') t.is(ctx.exitCode, 0) t.is( b4a.toString(await ctx.vfs.readFile('~/out.txt'), 'utf8'), 'pipeline-data\n' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine pipeline first stage stdin < file only', async (t) => { const dir = testCorestoreDir('shpipein') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('spin')) await drive.ready() await personal.ready() const cat = ` function bareStdin(ctx) { return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : '' } async function run(ctx) { ctx.console.log(bareStdin(ctx).replace(/\\n$/, '')) } ` const wcPath = path.join(__dirname, '../../kernel/bin/wc') const wcSrc = await readFile(wcPath, 'utf8') await drive.put('/bin/cat', b4a.from(cat)) await drive.put('/bin/wc', b4a.from(wcSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await ctx.vfs.writeFile('~/lines.txt', b4a.from('a\nb\nc\n')) await execShellLine(ctx, 'wc -l < ~/lines.txt | cat') t.is(ctx.exitCode, 0) t.ok(lines.some((l) => /^\s*3\s/.test(l) || l.includes('3'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine pipeline stage and byte limits', async (t) => { const dir = testCorestoreDir('shpipe') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('spipe')) await drive.ready() await personal.ready() const echo = ` async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) } ` const cat = ` function bareStdin(ctx) { return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : '' } async function run(ctx) { ctx.console.log(bareStdin(ctx).replace(/\\n$/, '')) } ` await drive.put('/bin/echo', b4a.from(echo)) await drive.put('/bin/cat', b4a.from(cat)) const spam = ` async function run(ctx) { ctx.console.log('z'.repeat(200)) } ` await drive.put('/bin/spam', b4a.from(spam)) const logs = [] const ctx = testCtx(drive, personal) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } ctx.env.BARE_OS_PIPELINE_MAX_STAGES = '2' await execShellLine(ctx, 'echo a | echo b | echo c') t.is(ctx.exitCode, 1) t.ok(logs.some((l) => l.includes('BARE_OS_PIPELINE_MAX_STAGES'))) logs.length = 0 ctx.env.BARE_OS_PIPELINE_MAX_STAGES = '32' ctx.env.BARE_OS_PIPELINE_MAX_BYTES = '80' await execShellLine(ctx, 'spam | cat') t.is(ctx.exitCode, 1) t.ok(logs.some((l) => l.includes('BARE_OS_PIPELINE_MAX_BYTES'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ls bareOsStdoutCaptured lists one name per line', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const lsSrc = await readFile(lsPath, 'utf8') const dir = testCorestoreDir('lscap') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('plcap')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await ctx.vfs.writeFile('aaa', b4a.from('')) await ctx.vfs.writeFile('lib', b4a.from('')) await ctx.vfs.writeFile('zzz', b4a.from('')) await runBinCommand(Object.assign({}, ctx, { bareOsStdoutCaptured: true }), [ 'ls' ]) t.is(lines.length, 3) t.ok(lines.includes('aaa') && lines.includes('lib') && lines.includes('zzz')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine ls pipe grep prints only matching entry line', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const grepPath = path.join(__dirname, '../../kernel/bin/grep') const lsSrc = await readFile(lsPath, 'utf8') const grepSrc = await readFile(grepPath, 'utf8') const dir = testCorestoreDir('lspipegrep') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('plpg')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) await drive.put('/bin/grep', b4a.from(grepSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await ctx.vfs.writeFile('aaa', b4a.from('')) await ctx.vfs.writeFile('lib', b4a.from('')) await ctx.vfs.writeFile('zzz', b4a.from('')) await execShellLine(ctx, 'ls | grep -F lib') t.is(ctx.exitCode, 0) t.alike(lines, ['lib']) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine ls pipe wc -l counts lines', async (t) => { const lsPath = path.join(__dirname, '../../kernel/bin/ls') const wcPath = path.join(__dirname, '../../kernel/bin/wc') const lsSrc = await readFile(lsPath, 'utf8') const wcSrc = await readFile(wcPath, 'utf8') const dir = testCorestoreDir('lspipewc') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('plwc')) await drive.ready() await personal.ready() await drive.put('/bin/ls', b4a.from(lsSrc)) await drive.put('/bin/wc', b4a.from(wcSrc)) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await ctx.vfs.writeFile('a', b4a.from('')) await ctx.vfs.writeFile('b', b4a.from('')) await ctx.vfs.writeFile('c', b4a.from('')) await execShellLine(ctx, 'ls | wc -l') t.is(ctx.exitCode, 0) const out = lines.join('\n').trim() t.is(out, '3', 'three directory entries => three lines') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine runs cd and external', async (t) => { const dir = testCorestoreDir('sh') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psh')) await drive.ready() await personal.ready() await drive.put( '/bin/xy', b4a.from(` async function run(ctx, argv) { ctx.got.push(argv.join(' ')) } `) ) const got = [] const ctx = testCtx(drive, personal) ctx.got = got await execShellLine(ctx, 'cd /bin') t.is(ctx.vfs.getcwd(), '/bin') await execShellLine(ctx, 'xy one two') t.is(got[0], 'xy one two') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine expands default ll to ls -la', async (t) => { const dir = testCorestoreDir('llalias') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('lla')) await drive.ready() await personal.ready() await drive.put( '/bin/ls', b4a.from(` async function run(ctx, argv) { ctx.got.push(argv.join(' ')) } `) ) const got = [] const ctx = testCtx(drive, personal) ctx.got = got await execShellLine(ctx, 'll one') t.is(got[0], 'ls -la one') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tokenize && || ; and split helpers', async (t) => { const toks = tokenize('a&&b||c;d') t.is(toks.map((x) => x.value).join(' '), 'a && b || c ; d') const lists = splitTokensBySemicolon(toks) t.is(lists.length, 2) const { segments, ops } = splitTokensByAndOr(lists[0]) t.is(segments.length, 3) t.is(ops.join(' '), '&& ||') }) test('execShellLine && || ; short-circuit and exitCode', async (t) => { const dir = testCorestoreDir('shandor') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('sand')) await drive.ready() await personal.ready() const stub = ` async function run(ctx, argv) { const c = argv[0] ctx.ran.push(c) ctx.exitCode = c === 'false' ? 1 : 0 } ` await drive.put('/bin/true', b4a.from(stub)) await drive.put('/bin/false', b4a.from(stub)) await drive.put( '/bin/rec', b4a.from(` async function run(ctx, argv) { ctx.ran.push('rec') ctx.exitCode = 0 } `) ) const ran = [] const ctx = testCtx(drive, personal) ctx.ran = ran ctx.exitCode = 0 await execShellLine(ctx, 'false && rec') t.is(ran.join(','), 'false') t.is(ctx.exitCode, 1) ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'false || rec') t.is(ran.join(','), 'false,rec') t.is(ctx.exitCode, 0) ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'true && rec') t.is(ran.join(','), 'true,rec') t.is(ctx.exitCode, 0) ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'true || rec') t.is(ran.join(','), 'true') t.is(ctx.exitCode, 0) ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'false || false || rec') t.is(ran.join(','), 'false,false,rec') t.is(ctx.exitCode, 0) ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'true && false || rec') t.is(ran.join(','), 'true,false,rec') t.is(ctx.exitCode, 0) ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'true; rec') t.is(ran.join(','), 'true,rec') await drive.put( '/bin/last', b4a.from(` async function run(ctx, argv) { ctx.ran.push('last') ctx.exitCode = 0 } `) ) ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'false | last') t.is(ran.join(','), 'false,last', 'pipeline runs both stages') t.is(ctx.exitCode, 0, 'POSIX-like: pipeline exit status is last stage') ran.length = 0 ctx.exitCode = 0 await execShellLine(ctx, 'BARE_OS_SHELL_PIPEFAIL=1 false | last') t.is(ran.join(','), 'false,last') t.is( ctx.exitCode, 1, 'pipefail: failure in an earlier stage overrides last stage success' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine if then else fi', async (t) => { const dir = testCorestoreDir('shif') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('sif')) await drive.ready() await personal.ready() await drive.put( '/bin/echo', b4a.from(` async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) } `) ) await drive.put( '/bin/true', b4a.from(` async function run(ctx) { ctx.exitCode = 0 } `) ) await drive.put( '/bin/false', b4a.from(` async function run(ctx) { ctx.exitCode = 1 } `) ) const lines = [] const ctx = testCtx(drive, personal) ctx.console = { log: (s) => lines.push(String(s)), error: (...a) => lines.push(a.join(' ')) } await execShellLine(ctx, 'if false; then echo no; else echo yes; fi') t.ok(lines.some((l) => l.includes('yes'))) lines.length = 0 await execShellLine(ctx, 'if true; then echo ok; fi') t.ok(lines.some((l) => l.includes('ok'))) lines.length = 0 await execShellLine(ctx, 'if false; then echo x; fi') t.ok(!lines.some((l) => l.includes('x'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('filenameFromContentDisposition parses attachment names', async (t) => { t.is( filenameFromContentDisposition('attachment; filename="a b.txt"'), 'a b.txt' ) t.is( filenameFromContentDisposition("attachment; filename*=UTF-8''x%20y.bin"), 'x y.bin' ) t.is(filenameFromContentDisposition(null), null) }) test('cron fieldMatches and dowFieldMatches', async (t) => { t.ok(fieldMatches('*', 0, 0, 59)) t.ok(fieldMatches('*/5', 10, 0, 59)) t.ok(!fieldMatches('*/5', 11, 0, 59)) t.ok(fieldMatches('1-3', 2, 0, 59)) t.ok(!fieldMatches('1-3', 4, 0, 59)) t.ok(fieldMatches('1,4', 1, 0, 59)) t.ok(fieldMatches('1,4', 4, 0, 59)) t.ok(fieldMatches('1-10/2', 3, 0, 59)) t.ok(!fieldMatches('1-10/2', 4, 0, 59)) t.ok(dowFieldMatches('7', 0)) t.ok(!dowFieldMatches('7', 1)) t.ok(dowFieldMatches('0', 0)) t.ok(dowFieldMatches('1-5', 3)) }) test('cron parseCronLine and jobMatchesDate', async (t) => { t.absent(parseCronLine('')) t.absent(parseCronLine('# comment')) t.absent(parseCronLine('0 0 * *')) const j = parseCronLine('30 14 15 6 * echo hello world') t.ok(j) t.is(j.command, 'echo hello world') const when = new Date(2020, 5, 15, 14, 30, 0) t.ok(jobMatchesDate(j, when)) t.ok(!jobMatchesDate(j, new Date(2020, 5, 15, 14, 31, 0))) const orJob = parseCronLine('0 12 15 * 1 echo dom-or-mon') t.ok(orJob) t.ok( jobMatchesDate(orJob, new Date(2020, 5, 15, 12, 0, 0)), '15th matches when dow also set (OR)' ) t.ok( jobMatchesDate(orJob, new Date(2020, 5, 8, 12, 0, 0)), 'Monday matches when dom also set (OR)' ) t.ok(!jobMatchesDate(orJob, new Date(2020, 5, 16, 12, 0, 0)), 'Tue 16th no match') const reboot = parseCronLine('@reboot echo hi') t.ok(reboot) t.is(reboot.minute, '@reboot') t.is(reboot.command, 'echo hi') t.ok(!jobMatchesDate(reboot, when)) const jit = parseCronLine('@reboot JitterSec=12 /bin/true') t.ok(jit) t.is(jit.jitterSec, 12) t.is(jit.command, '/bin/true') const jl = parseCronLine('* * * * * JitterSec=3 echo x') t.ok(jl) t.is(jl.jitterSec, 3) t.is(jl.command, 'echo x') }) test('systemctl list after startBareInitd shows kernel-logger and bare-cron', async (t) => { const dir = testCorestoreDir('initctl') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pinit')) await sys.ready() await personal.ready() const logs = [] const ctx = testCtx(sys, personal) ctx.execLine = async () => {} await startBareInitd(ctx) const dagRaw = getLastBareInitdDagSnapshotJson() const dag = JSON.parse(String(dagRaw).trim()) t.ok(dag && dag.supervision && dag.supervision.schema === 1) t.ok(Array.isArray(dag.supervision.restartKeys)) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } ctx.exitCode = 0 await runBinCommand(ctx, ['systemctl', 'list']) t.is(ctx.exitCode, 0) const text = logs.join('\n') t.ok(text.includes('kernel-logger')) t.ok(text.includes('bare-cron')) stopBareInitd() await store.close() rmSync(dir, { recursive: true, force: true }) }) test('systemctl list-units delegates to same backend', async (t) => { const dir = testCorestoreDir('initctlsys') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pics')) await sys.ready() await personal.ready() const logs = [] const ctx = testCtx(sys, personal) ctx.execLine = async () => {} await startBareInitd(ctx) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } ctx.exitCode = 0 await runBinCommand(ctx, ['systemctl', 'list-units']) t.is(ctx.exitCode, 0) t.ok(logs.join('\n').includes('bare-cron')) stopBareInitd() await store.close() rmSync(dir, { recursive: true, force: true }) }) test('systemctl is-active matches bare-initd runtime', async (t) => { const dir = testCorestoreDir('initctlactive') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pica')) await sys.ready() await personal.ready() const logs = [] const ctx = testCtx(sys, personal) ctx.execLine = async () => {} await startBareInitd(ctx) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } ctx.exitCode = 0 await runBinCommand(ctx, ['systemctl', 'is-active', 'kernel-logger']) t.is(ctx.exitCode, 0) t.ok(logs.join('\n').includes('active')) logs.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['systemctl', 'is-active', 'nonexistent-unit']) t.is(ctx.exitCode, 3) stopBareInitd() await store.close() rmSync(dir, { recursive: true, force: true }) }) test('systemctl restart bare-cron succeeds', async (t) => { const dir = testCorestoreDir('initctlrst') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('picr')) await sys.ready() await personal.ready() const logs = [] const ctx = testCtx(sys, personal) ctx.execLine = async () => {} await startBareInitd(ctx) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } ctx.exitCode = 0 await runBinCommand(ctx, ['systemctl', 'restart', 'bare-cron']) t.is(ctx.exitCode, 0) t.ok(logs.some((l) => /restarted bare-cron/i.test(l))) stopBareInitd() await store.close() rmSync(dir, { recursive: true, force: true }) }) test('initd disabled.txt skips unit on boot; systemctl enable undoes', async (t) => { const dir = testCorestoreDir('initdis') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pdis')) await sys.ready() await personal.ready() const ctx = testCtx(sys, personal) ctx.execLine = async () => {} await ctx.vfs.mkdir('/home/user/.config/bare-os/initd', { recursive: true }) await ctx.vfs.writeFile( '/home/user/.config/bare-os/initd/disabled.txt', b4a.from('bare-cron\n') ) await startBareInitd(ctx) t.is(getBareServiceRuntime('bare-cron'), undefined) t.is(getBareServiceRuntime('kernel-logger')?.phase, 'active') stopBareInitd() ctx.exitCode = 0 ctx.console = { log: () => {}, error: () => {} } await runBinCommand(ctx, ['systemctl', 'enable', 'bare-cron']) t.is(ctx.exitCode, 0) await startBareInitd(ctx) t.is(getBareServiceRuntime('bare-cron')?.phase, 'active') stopBareInitd() await store.close() rmSync(dir, { recursive: true, force: true }) }) test('stopBareInitd runs registered disposers', async (t) => { let n = 0 registerBareInitdDisposer(() => { n++ }) stopBareInitd() t.is(n, 1) stopBareInitd() t.is(n, 2) }) test('runKernelShutdownHooks runs LIFO once', async (t) => { const o = [] registerKernelShutdownHook(async () => { o.push('a') }) registerKernelShutdownHook(async () => { o.push('b') }) await runKernelShutdownHooks() t.is(o.join(','), 'b,a') await runKernelShutdownHooks() t.is(o.join(','), 'b,a') }) test('bareInitdShutdownActiveUnitsReverse is safe when nothing is active', async (t) => { stopBareInitd() await bareInitdShutdownActiveUnitsReverse({ vfs: null, console, env: {} }) t.pass() }) test('/proc/bare_os/clock.json is readable pseudo JSON', async (t) => { const dir = testCorestoreDir('clock-proc') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pc')) await drive.ready() await personal.ready() const bootStartedMs = Date.now() - 50 const shellEnv = { HOME: '/home/user', PATH: '/bin', USER: 'user', UID: '1000', GID: '1000', PWD: '/home/user', BARE_OS_EXIT_STATUS: '0' } const vfs = createVfs(drive, personal, shellEnv, null, { bareOsIpc: createBareOsIpc(), procBareOsClockText() { const wallMs = Date.now() return `${JSON.stringify({ schema: 1, CLOCK_REALTIME_MS: wallMs, CLOCK_BOOTTIME_RELATIVE_MS: wallMs - bootStartedMs, CLOCK_MONOTONIC_NS_FROM_PERF: null })}\n` } }) const raw = b4a.toString(await vfs.readFile('/proc/bare_os/clock.json')) const j = JSON.parse(raw) t.is(j.schema, 1) t.ok(typeof j.CLOCK_REALTIME_MS === 'number') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('/proc/self/fd lists extras from getProcSelfExtraFds', async (t) => { const dir = testCorestoreDir('self-fd-extra') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pc')) await drive.ready() await personal.ready() const shellEnv = { HOME: '/home/user', PATH: '/bin', USER: 'user', UID: '1000', GID: '1000', PWD: '/home/user', BARE_OS_EXIT_STATUS: '0' } const vfs = createVfs(drive, personal, shellEnv, null, { bareOsIpc: createBareOsIpc(), getProcSelfExtraFds: () => [{ fdNum: '7', target: 'pipe:[bare-test]' }] }) const names = await vfs.readdir('/proc/self/fd') t.ok(names.includes('7')) const txt = b4a.toString(await vfs.readFile('/proc/self/fd/7')) t.ok(txt.includes('pipe:[bare-test]')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('fish-readline stripAnsi and fuzzyMatch', async (t) => { t.is(stripAnsi('\x1b[32mhi\x1b[0m'), 'hi') t.ok(fuzzyMatch('hello', 'hlo')) t.ok(!fuzzyMatch('hello', 'hxo')) }) test('fish-readline history parse format dedupe search', async (t) => { const parsed = parseHistoryFile('#1:a\n#2:b\n') t.is(parsed.length, 2) t.is(parsed[0].command, 'a') const round = parseHistoryFile(formatHistoryFile(parsed)) t.is(round[1].command, 'b') const deduped = dedupeConsecutiveHistory([ { timestamp: 1, command: 'x' }, { timestamp: 2, command: 'x' }, { timestamp: 3, command: 'y' } ]) t.is(deduped.length, 2) t.is(deduped[1].command, 'y') const hist = [{ command: 'aa' }, { command: 'ba' }] const found = searchHistoryEntries(hist, 'a') t.ok(found.includes('ba')) t.ok(found.includes('aa')) }) test('tier-1 cat from system drive', async (t) => { const dir = testCorestoreDir('cat') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pc')) await drive.ready() await personal.ready() await drive.put('/bin/cat', b4a.from(await readBuiltBin('cat'))) await drive.put('/etc/x', b4a.from('hello')) const ctx = testCtx(drive, personal) ctx.console = { log() {}, error() {} } const catOut = [] const prevCatWrite = process.stdout.write process.stdout.write = (chunk) => { catOut.push( typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8') ) return true } try { await runBinCommand(ctx, ['cat', '/etc/x']) } finally { process.stdout.write = prevCatWrite } t.is(catOut.join(''), 'hello') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 tail head options and tail -f poll', async (t) => { const dir = testCorestoreDir('tail-head') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pth')) await drive.ready() await personal.ready() await drive.put('/bin/tail', b4a.from(await readBuiltBin('tail'))) await drive.put('/bin/head', b4a.from(await readBuiltBin('head'))) const lines = [] const ctx = testCtx(drive, personal, { BARE_OS_TAIL_F_POLL_MS: '25', BARE_OS_TAIL_F_MAX_ROUNDS: '8' }) ctx.exitCode = 0 ctx.bareOsRuntimeCaps = buildBareOsRuntimeCaps(ctx.env) ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('t.txt', b4a.from('one\ntwo\nthree\n')) await runBinCommand(ctx, ['tail', '-n', '2', 't.txt']) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), 'two\nthree') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['tail', '-n', '+2', 't.txt']) t.is(lines.join('\n'), 'two\nthree') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['head', '-c', '4', 't.txt']) t.is(lines[0], 'one\n') lines.length = 0 ctx.exitCode = 0 await ctx.vfs.writeFile('f.log', b4a.from('a\n')) const tailP = runBinCommand(ctx, ['tail', '-f', 'f.log']) await new Promise((r) => setTimeout(r, 15)) const cur = b4a.toString(await ctx.vfs.readFile('f.log')) await ctx.vfs.writeFile('f.log', b4a.from(cur + 'b\n')) await tailP t.ok(lines.includes('a')) t.ok(lines.includes('b')) lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = 'x\ny\n' await runBinCommand(ctx, ['tail', '-f']) t.is(ctx.exitCode, 1) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 grep and mkfifo from system drive', async (t) => { const dir = testCorestoreDir('grep') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pg')) await drive.ready() await personal.ready() await drive.put('/bin/grep', b4a.from(await readBuiltBin('grep'))) await drive.put('/bin/mkfifo', b4a.from(await readBuiltBin('mkfifo'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile( 'w.txt', b4a.from('aaa\nneedle line\nbbb\nneedle line two') ) await runBinCommand(ctx, ['grep', '-F', 'needle', 'w.txt']) t.is(ctx.exitCode, 0) t.is(lines.length, 2) t.ok(lines[0].includes('needle line')) t.ok(lines[1].includes('needle line two')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-F', 'nomatch', 'w.txt']) t.is(ctx.exitCode, 1) t.is(lines.length, 0) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-v', '-F', 'needle', 'w.txt']) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), 'aaa\nbbb') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-c', '-F', 'needle', 'w.txt']) t.is(ctx.exitCode, 0) t.is(lines[0], '2') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-n', '-F', 'bbb', 'w.txt']) t.is(ctx.exitCode, 0) t.is(lines[0], '3:bbb') lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = 'alpha\nbeta\n' await runBinCommand(ctx, ['grep', '-F', 'beta']) t.is(ctx.exitCode, 0) t.is(lines[0], 'beta') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-x', '-F', 'aaa', 'w.txt']) t.is(ctx.exitCode, 0) t.is(lines[0], 'aaa') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-m', '1', '-F', 'needle', 'w.txt']) t.is(ctx.exitCode, 0) t.is(lines.length, 1) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-o', 'ee', 'w.txt']) t.is(ctx.exitCode, 0) t.ok(lines.includes('ee')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['mkfifo', '/run/bare-os/ipc/t1']) t.is(ctx.exitCode, 0) const readP = ctx.vfs.readFile('/run/bare-os/ipc/t1') await ctx.vfs.writeFile('/run/bare-os/ipc/t1', b4a.from('ok')) t.is(b4a.toString(await readP), 'ok') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['grep', '-F', '-C', '1', 'needle', 'w.txt']) t.is(ctx.exitCode, 0) t.ok(lines.some((l) => l === 'aaa')) t.ok(lines.some((l) => l.includes('needle line'))) t.ok(lines.some((l) => l === 'bbb')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 sort and wc flags', async (t) => { const dir = testCorestoreDir('sort-wc') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psw')) await drive.ready() await personal.ready() await drive.put('/bin/sort', b4a.from(await readBuiltBin('sort'))) await drive.put('/bin/wc', b4a.from(await readBuiltBin('wc'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('nums.txt', b4a.from('10\n2\n1\n')) await runBinCommand(ctx, ['sort', '-n', 'nums.txt']) t.is(lines.join('\n'), '1\n2\n10') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sort', '-nru', 'nums.txt']) t.is(lines.join('\n'), '10\n2\n1') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['wc', '-l', 'nums.txt']) t.is(lines[0].trim(), '3 nums.txt') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['wc', '-c', 'nums.txt']) t.is(lines[0], ' 7 nums.txt') const errs = [] ctx.console = { log(s) { lines.push(String(s)) }, error(...a) { errs.push(a.join(' ')) } } await ctx.vfs.writeFile('ord.txt', b4a.from('a\nb\nc\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sort', '-c', 'ord.txt']) t.is(ctx.exitCode, 0) t.is(errs.length, 0) await ctx.vfs.writeFile('bad.txt', b4a.from('b\na\n')) lines.length = 0 errs.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sort', '-c', 'bad.txt']) t.is(ctx.exitCode, 1) t.ok(errs.some((e) => e.includes('disorder'))) errs.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sort', '-C', 'bad.txt']) t.is(ctx.exitCode, 1) t.is(errs.length, 0) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sort', '-o', 'sorted.txt', '-n', 'nums.txt']) t.is(ctx.exitCode, 0) const sortedBuf = await ctx.vfs.readFile('sorted.txt') t.is(ctx.b4a.toString(sortedBuf), '1\n2\n10\n') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sort', '-s', 'ord.txt']) t.is(lines.join('\n'), 'a\nb\nc') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 find du basename options', async (t) => { const dir = testCorestoreDir('fdu-base') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pfdb')) await drive.ready() await personal.ready() await drive.put('/bin/find', b4a.from(await readBuiltBin('find'))) await drive.put('/bin/du', b4a.from(await readBuiltBin('du'))) await drive.put('/bin/basename', b4a.from(await readBuiltBin('basename'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('Lo.txt', b4a.from('ab')) await runBinCommand(ctx, ['find', '.', '-iname', 'lo.txt']) t.is(ctx.exitCode, 0) t.ok(lines.some((p) => /Lo\.txt$/.test(String(p).replace(/\\/g, '/')))) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['du', '-h', 'Lo.txt']) t.ok(/^2\tLo\.txt$/.test(lines[0]) || /^3\tLo\.txt$/.test(lines[0])) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['basename', '-a', '/x/a', '/y/b']) t.is(lines.join('\n'), 'a\nb') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['basename', 'z.h', '.h']) t.is(lines[0], 'z') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('execShellLine find pipes to wc -l', async (t) => { const dir = testCorestoreDir('findpipewc') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('fpwc')) await drive.ready() await personal.ready() await drive.put('/bin/find', b4a.from(await readBuiltBin('find'))) await drive.put('/bin/wc', b4a.from(await readBuiltBin('wc'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('p.txt', b4a.from('')) await execShellLine(ctx, 'find . -maxdepth 1 | wc -l') t.is(ctx.exitCode, 0) const n = Number.parseInt(String(lines[0] || '').trim(), 10) t.ok(Number.isFinite(n) && n >= 1) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 date format and test numeric', async (t) => { const dir = testCorestoreDir('date-test') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pdt')) await drive.ready() await personal.ready() await drive.put('/bin/date', b4a.from(await readBuiltBin('date'))) await drive.put('/bin/test', b4a.from(await readBuiltBin('test'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await runBinCommand(ctx, ['test', '2', '-lt', '5']) t.is(ctx.exitCode, 0) await runBinCommand(ctx, ['test', '5', '-lt', '2']) t.is(ctx.exitCode, 1) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['date', '+%Y']) t.is(ctx.exitCode, 0) t.ok(/^\d{4}$/.test(lines[0])) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 find -mindepth skips shallow paths', async (t) => { const dir = testCorestoreDir('find-mindepth') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pfindmd')) await drive.ready() await personal.ready() await drive.put('/bin/find', b4a.from(await readBuiltBin('find'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.mkdir('nest', { recursive: true }) await ctx.vfs.mkdir('nest/sub', { recursive: true }) await ctx.vfs.writeFile('nest/a.txt', b4a.from('a')) await ctx.vfs.writeFile('nest/sub/b.txt', b4a.from('b')) await runBinCommand(ctx, ['find', '.', '-mindepth', '2', '-type', 'f']) t.is(ctx.exitCode, 0) const norm = lines.map((p) => p.replace(/\\/g, '/')).sort() t.ok(norm.some((p) => p.endsWith('/nest/a.txt'))) t.ok(norm.some((p) => p.endsWith('/nest/sub/b.txt'))) lines.length = 0 await runBinCommand(ctx, ['find', 'nest', '-mindepth', '2', '-type', 'f']) t.is(ctx.exitCode, 0) t.ok( lines.some((p) => String(p).replace(/\\/g, '/').endsWith('/nest/sub/b.txt')) ) t.ok( !lines.some((p) => String(p).replace(/\\/g, '/').endsWith('/nest/a.txt')) ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs union write deny rejects chmod and symlink targets', async (t) => { const dir = testCorestoreDir('union-deny') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pu')) await sys.ready() await personal.ready() const shellEnv = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin', USER: 'guest', UID: '0', GID: '0' } const vfs = createVfs(sys, personal, shellEnv, null, { bareOsIpc: createBareOsIpc(), unionReadPrefixes: ['/etc'], unionWriteDenyPrefixes: ['/etc'] }) let w = false try { await vfs.writeFile('/etc/union-blocked', b4a.from('x')) } catch (e) { w = true t.ok(String(e.message).includes('union write denied')) } t.ok(w) let c = false try { await vfs.chmod('/etc/passwd', 0o644) } catch (e) { c = true t.ok(String(e.message).includes('union write denied')) } t.ok(c) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs symlink relative and absolute targets under personal', async (t) => { const dir = testCorestoreDir('symlink-personal') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('slp')) await drive.ready() await personal.ready() const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('~/target.txt', b4a.from('hello')) await ctx.vfs.symlink('target.txt', '~/via_rel.txt') t.is(await ctx.vfs.readlink('~/via_rel.txt'), 'target.txt') const st = await ctx.vfs.lstat('~/via_rel.txt') t.is(st.type, 'symlink') t.is(b4a.toString(await ctx.vfs.readFile('~/via_rel.txt'), 'utf8'), 'hello') await ctx.vfs.symlink('/home/user/target.txt', '~/via_abs.txt') t.is(await ctx.vfs.readlink('~/via_abs.txt'), '/home/user/target.txt') t.is(b4a.toString(await ctx.vfs.readFile('~/via_abs.txt'), 'utf8'), 'hello') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('vfs symlink on system drive /var follows within same drive', async (t) => { const dir = testCorestoreDir('symlink-system-var') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('slsv')) await drive.ready() await personal.ready() const dataPath = '/var/bare-os-symlink-test/data.txt' const aliasPath = '/var/bare-os-symlink-test/alias.txt' await drive.put(dataPath, b4a.from('sysblob')) await drive.symlink(aliasPath, dataPath, { metadata: {} }) const ctx = testCtx(drive, personal) t.is(await ctx.vfs.readlink(aliasPath), dataPath) t.is(b4a.toString(await ctx.vfs.readFile(aliasPath), 'utf8'), 'sysblob') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('HyperDHT local testnet: bootstrap node and ephemeral peer fullyBootstrapped', async (t) => { const createTestnet = require('hyperdht/testnet.js') const DHT = require('hyperdht') const testnet = await createTestnet(1) try { t.ok(testnet.bootstrap.length >= 1, 'testnet exposes bootstrap address') const addr = testnet.nodes[0].address() t.ok(addr && addr.port > 0, 'bootstrap listens on a UDP port') const client = new DHT({ ephemeral: true, bootstrap: testnet.bootstrap, host: '127.0.0.1' }) try { await client.fullyBootstrapped() t.pass('ephemeral HyperDHT node reaches fullyBootstrapped against local testnet') } finally { await client.destroy() } } finally { await testnet.destroy() } }) test('tier-1 mv renames file in home', async (t) => { const dir = testCorestoreDir('mv-home') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('mvhm')) await drive.ready() await personal.ready() await drive.put('/bin/mv', b4a.from(await readBuiltBin('mv'))) const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('a.txt', b4a.from('ok')) ctx.exitCode = 0 await runBinCommand(ctx, ['mv', 'a.txt', 'b.txt']) t.is(ctx.exitCode, 0) t.is(b4a.toString(await ctx.vfs.readFile('b.txt'), 'utf8'), 'ok') t.ok( (await ctx.vfs.readFile('a.txt')) == null, 'mv removed source path in home' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 cmp silent and kernel-boot-diff line set', async (t) => { const dir = testCorestoreDir('cmp-kbd') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('cmpkbd')) await drive.ready() await personal.ready() const cmpSrc = await readFile( path.join(__dirname, '../../kernel/bin/cmp'), 'utf8' ) const kbdSrc = await readFile( path.join(__dirname, '../../kernel/bin/kernel-boot-diff'), 'utf8' ) await drive.put('/bin/cmp', b4a.from(cmpSrc)) await drive.put('/bin/kernel-boot-diff', b4a.from(kbdSrc)) const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('same1.txt', b4a.from('x')) await ctx.vfs.writeFile('same2.txt', b4a.from('x')) ctx.exitCode = 0 await runBinCommand(ctx, ['cmp', '-s', 'same1.txt', 'same2.txt']) t.is(ctx.exitCode, 0, 'cmp -s identical') await ctx.vfs.writeFile('d2.txt', b4a.from('y')) ctx.exitCode = 0 const errs = [] ctx.console = { log() {}, error(s) { errs.push(String(s)) } } await runBinCommand(ctx, ['cmp', '-s', 'same1.txt', 'd2.txt']) t.is(ctx.exitCode, 1, 'cmp -s differs') await ctx.vfs.writeFile('boot-a.txt', b4a.from('line1\nline2\n')) await ctx.vfs.writeFile('boot-b.txt', b4a.from('line1\nline3\n')) const lines = [] ctx.console = { log(s) { lines.push(String(s)) }, error(s) { errs.push(String(s)) } } ctx.exitCode = 0 await runBinCommand(ctx, ['kernel-boot-diff', 'boot-a.txt', 'boot-b.txt']) t.is(ctx.exitCode, 0) t.ok(lines.some((l) => l.startsWith('+ ') && l.includes('line3'))) t.ok(lines.some((l) => l.startsWith('- ') && l.includes('line2'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 diff -u and patch apply stdin hunk', async (t) => { const dir = testCorestoreDir('diffpatch') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('dp')) await drive.ready() await personal.ready() await drive.put('/bin/diff', b4a.from(await readBuiltBin('diff'))) await drive.put('/bin/patch', b4a.from(await readBuiltBin('patch'))) const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('a.txt', b4a.from('alpha\n')) await ctx.vfs.writeFile('b.txt', b4a.from('beta\n')) const out = [] ctx.console = { log(s) { out.push(String(s)) }, error() {} } ctx.exitCode = 0 await runBinCommand(ctx, ['diff', '-u', 'a.txt', 'b.txt']) t.is(ctx.exitCode, 1) t.ok(out.join('\n').includes('+++ b.txt')) await ctx.vfs.writeFile('fix.txt', b4a.from('alpha\n')) ctx.shellStdin = out.join('\n') + '\n' ctx.exitCode = 0 await runBinCommand(ctx, ['patch', '-p0', 'fix.txt']) t.is(ctx.exitCode, 0) t.is(ctx.b4a.toString(await ctx.vfs.readFile('fix.txt')), 'beta\n') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('bareInitdReadinessSnapshot exposes unit table', async (t) => { const s = bareInitdReadinessSnapshot() t.is(s.schema, 2) t.ok(Array.isArray(s.units)) t.ok(s.supervisionTelemetry && s.supervisionTelemetry.schema === 1) }) test('tier-1 test -r -w -x -s predicates', async (t) => { const dir = testCorestoreDir('test-pred') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('tpred')) await drive.ready() await personal.ready() await drive.put('/bin/test', b4a.from(await readBuiltBin('test'))) const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('ro.txt', b4a.from('data')) await ctx.vfs.chmod('ro.txt', 0o400) ctx.exitCode = 0 await runBinCommand(ctx, ['test', '-r', 'ro.txt']) t.is(ctx.exitCode, 0, '-r read-only file') ctx.exitCode = 0 await runBinCommand(ctx, ['test', '-w', 'ro.txt']) t.is(ctx.exitCode, 1, '-w false when not writable') ctx.exitCode = 0 await runBinCommand(ctx, ['test', '-s', 'ro.txt']) t.is(ctx.exitCode, 0, '-s nonempty file') await ctx.vfs.writeFile('empty.txt', b4a.from('')) ctx.exitCode = 0 await runBinCommand(ctx, ['test', '-s', 'empty.txt']) t.is(ctx.exitCode, 1, '-s empty file') await ctx.vfs.writeFile('run.sh', b4a.from('#!')) await ctx.vfs.chmod('run.sh', 0o700) ctx.exitCode = 0 await runBinCommand(ctx, ['test', '-x', 'run.sh']) t.is(ctx.exitCode, 0, '-x executable') await ctx.vfs.chmod('run.sh', 0o600) ctx.exitCode = 0 await runBinCommand(ctx, ['test', '-x', 'run.sh']) t.is(ctx.exitCode, 1, '-x false without exec bit') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 find -perm filters by mode', async (t) => { const dir = testCorestoreDir('find-perm') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pfp')) await drive.ready() await personal.ready() await drive.put('/bin/find', b4a.from(await readBuiltBin('find'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('rw.txt', b4a.from('')) await ctx.vfs.chmod('rw.txt', 0o644) await ctx.vfs.writeFile('x.txt', b4a.from('')) await ctx.vfs.chmod('x.txt', 0o600) await runBinCommand(ctx, ['find', '.', '-perm', '600', '-type', 'f']) t.is(ctx.exitCode, 0) t.ok( lines.some((p) => String(p).replace(/\\/g, '/').endsWith('/x.txt')) ) t.ok( !lines.some((p) => String(p).replace(/\\/g, '/').endsWith('/rw.txt')) ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 find -mtime -1 matches recent files', async (t) => { const dir = testCorestoreDir('find-mtime') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('fmt')) await drive.ready() await personal.ready() await drive.put('/bin/find', b4a.from(await readBuiltBin('find'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('recent.txt', b4a.from('x')) await runBinCommand(ctx, ['find', '.', '-type', 'f', '-mtime', '-1']) t.is(ctx.exitCode, 0) t.ok( lines.some((p) => String(p).replace(/\\/g, '/').endsWith('/recent.txt')) ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 find -xdev skips other volume under /', async (t) => { const dir = testCorestoreDir('find-xdev') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('fxd')) await drive.ready() await personal.ready() await drive.put('/onlyroot.txt', b4a.from('sys')) await drive.put('/bin/find', b4a.from(await readBuiltBin('find'))) const ctx = testCtx(drive, personal, { PWD: '/', HOME: '/home/user' }) ctx.exitCode = 0 const lines = [] ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('/home/user/only_in_home.txt', b4a.from('p')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['find', '/', '-xdev', '-name', 'only_in_home.txt']) t.is(ctx.exitCode, 0) t.is(lines.length, 0, '-xdev from / must not descend into /home') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['find', '/', '-name', 'only_in_home.txt']) t.is(ctx.exitCode, 0) t.ok( lines.some((p) => String(p).replace(/\\/g, '/').endsWith('/only_in_home.txt') ), 'without -xdev, file under /home is visible from /' ) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['find', '/', '-xdev', '-name', 'onlyroot.txt']) t.is(ctx.exitCode, 0) t.ok( lines.some((p) => String(p).replace(/\\/g, '/').endsWith('/onlyroot.txt') ), '-xdev still searches system tree under /' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tar-cli hard link extract copies unless BARE_OS_VFS_STRICT_HARDLINK', async (t) => { const dir = testCorestoreDir('tar-hardlink') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('tarhl')) await drive.ready() await personal.ready() const body = b4a.from('hi', 'utf8') const hdrA = encodeUstarHeader({ name: 'a.txt', size: body.length, mode: 0o644, mtime: 1, typeflag: '0' }) const padA = new Uint8Array((TAR_BLK - (body.length % TAR_BLK)) % TAR_BLK) const hdrB = encodeUstarHeader({ name: 'b.txt', size: 0, mode: 0o644, mtime: 1, typeflag: '1', linkname: 'a.txt' }) const archive = concatTarParts([ hdrA, body, padA, hdrB, new Uint8Array(TAR_BLK * 2) ]) const errs = [] const ctx = testCtx(drive, personal) await ctx.vfs.writeFile('hl.tar', b4a.from(archive)) ctx.exitCode = 0 ctx.console = { log() {}, error(s) { errs.push(String(s)) } } await runTarCli(ctx, ['tar', '-xf', 'hl.tar']) t.is(ctx.exitCode, 0) t.is(b4a.toString(await ctx.vfs.readFile('b.txt'), 'utf8'), 'hi') await ctx.vfs.rm('a.txt', { recursive: true, force: true }) await ctx.vfs.rm('b.txt', { recursive: true, force: true }) errs.length = 0 ctx.exitCode = 0 await ctx.vfs.writeFile('hl.tar', b4a.from(archive)) const ctxStrict = testCtx(drive, personal, { BARE_OS_VFS_STRICT_HARDLINK: '1' }) await ctxStrict.vfs.writeFile('hl.tar', b4a.from(archive)) ctxStrict.exitCode = 0 ctxStrict.console = { log() {}, error(s) { errs.push(String(s)) } } await runTarCli(ctxStrict, ['tar', '-xf', 'hl.tar']) t.is(ctxStrict.exitCode, 1) t.ok( errs.some((e) => /hard link entries not supported/i.test(e)), 'strict mode rejects hard link members' ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 jq from system drive', async (t) => { const dir = testCorestoreDir('jq') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pjq')) await drive.ready() await personal.ready() await drive.put('/bin/jq', b4a.from(await readBuiltBin('jq'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.writeFile('data.json', b4a.from('{"x":42,"name":"hi"}')) await runBinCommand(ctx, ['jq', '.x', 'data.json']) t.is(ctx.exitCode, 0) t.is(lines[0], '42') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['jq', '-c', '.', 'data.json']) t.is(ctx.exitCode, 0) t.is(lines[0], '{"x":42,"name":"hi"}') lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = '{"a":1}' await runBinCommand(ctx, ['jq', '.a']) t.is(ctx.exitCode, 0) t.is(lines[0], '1') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 getconf and xargs from system drive', async (t) => { const dir = testCorestoreDir('gxc') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pgx')) await drive.ready() await personal.ready() await drive.put('/bin/getconf', b4a.from(await readBuiltBin('getconf'))) await drive.put( '/bin/echolog', b4a.from(` async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) } `) ) await drive.put('/bin/xargs', b4a.from(await readBuiltBin('xargs'))) await drive.put('/bin/false', b4a.from(await readBuiltBin('false'))) await drive.put('/bin/printf', b4a.from(await readBuiltBin('printf'))) const lines = [] const ctx = testCtx(drive, personal) ctx.runBinCommand = function (argv, ro) { return runBinCommand(this, argv, ro) } ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error(s) { lines.push(String(s)) } } await runBinCommand(ctx, ['getconf', 'PATH_MAX']) t.is(ctx.exitCode, 0) t.is(lines.pop(), '4096') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['getconf', 'BARE_OS_YES_MAX_LINES']) t.is(ctx.exitCode, 0) t.is(lines.pop(), '100000') lines.length = 0 ctx.exitCode = 0 ctx.bareOsPathconf = (p, n) => { void p if (n === '_PC_NAME_MAX') return 255 throw new Error('getconf pathconf test: unknown name') } await runBinCommand(ctx, ['getconf', '_PC_NAME_MAX', '/home/user']) t.is(ctx.exitCode, 0) t.is(lines.pop(), '255') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['getconf', 'NOT_A_REAL_CONF_NAME']) t.is(ctx.exitCode, 1) lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = 'hello\tworld\n' await runBinCommand(ctx, ['xargs', 'echolog']) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), 'hello world') lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = 'a\0b\0' await runBinCommand(ctx, ['xargs', '-0', '-n1', 'echolog']) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), 'a\nb') lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = 'one\ntwo\n' await runBinCommand(ctx, ['xargs', '-I', '{}', 'echolog', 'x', '{}', 'y']) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), 'x one y\nx two y') lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = 'a\nb\n' await runBinCommand(ctx, ['xargs', '-P2', '-n1', 'echolog']) t.is(ctx.exitCode, 0) t.is(new Set(lines).size, 2) t.ok(lines.includes('a')) t.ok(lines.includes('b')) lines.length = 0 ctx.exitCode = 0 ctx.vfs.env.BARE_OS_XARGS_MAX_PROCS = '2' ctx.shellStdin = 'x\ny\n' await runBinCommand(ctx, ['xargs', '-P8', '-n1', 'echolog']) t.is(ctx.exitCode, 0) t.ok(lines.some((s) => String(s).includes('exceeds cap 2'))) lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = '' await execShellLine(ctx, 'false || printf recovered') t.is(lines.pop(), 'recovered') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 sh shebang strip and symlink script path', async (t) => { const dir = testCorestoreDir('shshe') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psh')) await drive.ready() await personal.ready() await drive.put('/bin/sh', b4a.from(await readBuiltBin('sh'))) await drive.put( '/bin/echo', b4a.from(`async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) } `) ) const lines = [] const ctx = testCtx(drive, personal) ctx.runBinCommand = function (argv, ro) { return runBinCommand(this, argv, ro) } ctx.execLine = (line, opts) => execShellLine(ctx, line) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error(s) { lines.push(String(s)) } } await ctx.vfs.chdir('/home/user') await ctx.vfs.writeFile( 'real.sh', b4a.from('#!/bin/sh\necho shebang-ok\n') ) await ctx.vfs.symlink('real.sh', 'via.sh') await runBinCommand(ctx, ['sh', 'via.sh']) t.is(ctx.exitCode, 0) t.ok(lines.some((l) => String(l).includes('shebang-ok'))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-2 cat env touch mkdir', async (t) => { const dir = testCorestoreDir('tier2tem') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pt2')) await drive.ready() await personal.ready() for (const name of ['cat', 'env', 'touch', 'mkdir', 'printf']) { await drive.put('/bin/' + name, b4a.from(await readBuiltBin(name))) } const catOut = [] const lines = [] const ctx = testCtx(drive, personal, { MARK: 'parent', HELLO: 'world' }) ctx.exitCode = 0 ctx.runBinCommand = function (argv, o) { return runBinCommand(this, argv, o) } ctx.console = { log(s) { lines.push(String(s)) }, error(s) { lines.push('e:' + String(s)) } } await ctx.vfs.chdir('/home/user') await ctx.vfs.writeFile('plain.txt', b4a.from('a\nb\n')) const captureCat = async (argv) => { catOut.length = 0 const prevWrite = process.stdout.write process.stdout.write = (chunk) => { catOut.push( typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8') ) return true } try { ctx.exitCode = 0 await runBinCommand(ctx, argv) } finally { process.stdout.write = prevWrite } } await captureCat(['cat', '-n', 'plain.txt']) t.is(ctx.exitCode, 0) t.is(catOut.join(''), ' 1\ta\n 2\tb\n') await captureCat(['cat', '-A', 'plain.txt']) t.is(ctx.exitCode, 0) t.is(catOut.join(''), 'a$\nb$\n') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, [ 'env', '-i', 'PATH=/bin', 'HELLO=there', 'printf', '%s', 'ok' ]) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), 'ok') t.is(ctx.vfs.env.MARK, 'parent') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['touch', '-d', '@3600', 'ts.txt']) t.is(ctx.exitCode, 0) const stTs = await ctx.vfs.lstat('ts.txt') t.is(stTs && stTs.mtimeMs, 3600000) ctx.exitCode = 0 await runBinCommand(ctx, ['touch', 'ref.txt']) const stRef = await ctx.vfs.lstat('ref.txt') t.ok(stRef && typeof stRef.mtimeMs === 'number') ctx.exitCode = 0 await runBinCommand(ctx, ['touch', '-r', 'ref.txt', 'ts2.txt']) t.is(ctx.exitCode, 0) const st2 = await ctx.vfs.lstat('ts2.txt') t.is(st2 && st2.mtimeMs, stRef.mtimeMs) ctx.exitCode = 0 await runBinCommand(ctx, ['mkdir', '-m', '700', 'secret_dir']) t.is(ctx.exitCode, 0) const stD = await ctx.vfs.lstat('secret_dir') t.ok(stD && (stD.mode & 0o777) === 0o700) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('printenv -0 uses ctx.bareOsBinWrite when stdout is unavailable', async (t) => { const dir = testCorestoreDir('binw') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pbin')) await drive.ready() await personal.ready() await drive.put('/bin/printenv', b4a.from(await readBuiltBin('printenv'))) const raw = [] const ctx = testCtx(drive, personal, { ZZ: 'z', AA: 'a' }) ctx.exitCode = 0 ctx.runBinCommand = function (argv, o) { return runBinCommand(this, argv, o) } ctx.bareOsBinWrite = (u) => { raw.push(b4a.toString(u instanceof Uint8Array ? u : new Uint8Array(u))) } ctx.console = { log() {}, error() {} } await runBinCommand(ctx, ['printenv', '-0', 'AA', 'ZZ']) t.is(ctx.exitCode, 0) t.is(raw.join(''), 'a\0z\0') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('sed and awk golden one-liners', async (t) => { const dir = testCorestoreDir('sawk') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psawk')) await drive.ready() await personal.ready() await drive.put('/bin/sed', b4a.from(await readBuiltBin('sed'))) await drive.put('/bin/awk', b4a.from(await readBuiltBin('awk'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error() {} } await ctx.vfs.chdir('/home/user') await ctx.vfs.writeFile('f.txt', b4a.from('abc\ndef\n')) await runBinCommand(ctx, ['sed', '-e', 's/a/X/', 'f.txt']) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), 'Xbc\ndef') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['awk', '{ print NF }', 'f.txt']) t.is(ctx.exitCode, 0) t.is(lines.join('\n'), '1\n1') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('curl delegated from booter with stub fetch', async (t) => { const dir = testCorestoreDir('curl') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pcurl')) await drive.ready() await personal.ready() const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error(s) { lines.push('e:' + String(s)) } } /** @type {RequestInit | undefined} */ let curlInitHello ctx.httpFetch = async (_url, init) => { curlInitHello = init return new Response('hello', { status: 200, headers: { 'Content-Type': 'text/plain' } }) } await runBinCommand(ctx, ['curl', 'https://stub.example/x']) t.is(ctx.exitCode, 0) t.is(lines[0], 'hello') t.is(headerFromInit(curlInitHello, 'User-Agent'), DEFAULT_CURL_USER_AGENT) lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async () => new Response('', { status: 404 }) await runBinCommand(ctx, ['curl', '-f', '-s', 'https://stub.example/missing']) t.is(ctx.exitCode, 22) lines.length = 0 ctx.exitCode = 0 let curlSeenUrl = '' /** @type {RequestInit | undefined} */ let curlSeenInit ctx.httpFetch = async (url, init) => { curlSeenUrl = String(url) curlSeenInit = init return new Response('', { status: 200 }) } await runBinCommand(ctx, ['curl', 'example.com', '-IL']) t.is(ctx.exitCode, 0) t.is(curlSeenUrl, 'http://example.com') t.is(curlSeenInit && curlSeenInit.method, 'HEAD') lines.length = 0 ctx.exitCode = 0 /** @type {{ url: string, method: string }[]} */ const curlHopCalls = [] ctx.httpFetch = async (url, init) => { const u = String(url) const method = String(init?.method || 'GET') curlHopCalls.push({ url: u, method }) if (method === 'HEAD' && u === 'http://hop.example/start') { return new Response('', { status: 302, headers: { Location: 'https://hop.example/done' } }) } if (method === 'GET' && u === 'https://hop.example/done') { return new Response('secret-body', { status: 200, headers: { 'Content-Type': 'text/plain' } }) } return new Response('unexpected', { status: 500 }) } await runBinCommand(ctx, ['curl', '-IL', 'http://hop.example/start']) t.is(ctx.exitCode, 0) t.is(curlHopCalls.length, 2) t.is(curlHopCalls[0].method, 'HEAD') t.is(curlHopCalls[1].method, 'GET') t.ok(lines[0].includes('200')) t.ok(!lines[0].includes('secret-body')) lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async (url) => { curlSeenUrl = String(url) return new Response('', { status: 200 }) } await runBinCommand(ctx, ['curl', '-I', '//stub.example/p']) t.is(ctx.exitCode, 0) t.is(curlSeenUrl, 'https://stub.example/p') lines.length = 0 ctx.exitCode = 0 /** @type {RequestInit | undefined} */ let curlInitUa ctx.httpFetch = async (_url, init) => { curlInitUa = init return new Response('x', { status: 200 }) } await runBinCommand(ctx, [ 'curl', '-A', 'CustomCurlUA/9', 'https://stub.example/ua' ]) t.is(ctx.exitCode, 0) t.is(headerFromInit(curlInitUa, 'User-Agent'), 'CustomCurlUA/9') lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async (_url, init) => { curlInitUa = init return new Response('x', { status: 200 }) } await runBinCommand(ctx, [ 'curl', '-H', 'User-Agent: from-header', '-A', 'from-flag', 'https://stub.example/ua2' ]) t.is(ctx.exitCode, 0) t.is(headerFromInit(curlInitUa, 'User-Agent'), 'from-flag') lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async (_url, init) => { curlInitUa = init return new Response('x', { status: 200 }) } await runBinCommand(ctx, [ 'curl', '-A', 'from-flag', '-H', 'User-Agent: from-header', 'https://stub.example/ua3' ]) t.is(ctx.exitCode, 0) t.is(headerFromInit(curlInitUa, 'User-Agent'), 'from-header') lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async () => new Response('body-o', { status: 200, headers: { 'Content-Type': 'text/plain' } }) await runBinCommand(ctx, [ 'curl', '-sO', 'https://stub.example/dir/named.txt' ]) t.is(ctx.exitCode, 0) const named = await ctx.vfs.readFile('named.txt') t.is(ctx.b4a.toString(named), 'body-o') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['curl', '-o', 'x', '-O', 'https://stub.example/y']) t.is(ctx.exitCode, 2) lines.length = 0 ctx.exitCode = 0 /** @type {{ url: string, method: string }[]} */ const curlRedirectCountCalls = [] ctx.httpFetch = async (url, init) => { const u = String(url) const method = String(init?.method || 'GET') curlRedirectCountCalls.push({ url: u, method }) if (method === 'HEAD' && u === 'http://rc.example/a') { return new Response('', { status: 302, headers: { Location: 'https://rc.example/b' } }) } if (method === 'GET' && u === 'https://rc.example/b') { return new Response('', { status: 200 }) } return new Response('bad', { status: 500 }) } await runBinCommand(ctx, [ 'curl', '-s', '-w', '%{num_redirects}', '-o', 'hdr.dump', '-IL', 'http://rc.example/a' ]) t.is(ctx.exitCode, 0) t.is(lines[lines.length - 1], '1') lines.length = 0 ctx.exitCode = 0 /** @type {RequestInit | undefined} */ let curlCookieInit ctx.httpFetch = async (_url, init) => { curlCookieInit = init return new Response('c', { status: 200 }) } await runBinCommand(ctx, [ 'curl', '-b', 'sid=abc', 'https://stub.example/cookie-inline' ]) t.is(ctx.exitCode, 0) t.is(headerFromInit(curlCookieInit, 'Cookie'), 'sid=abc') lines.length = 0 ctx.exitCode = 0 await ctx.vfs.writeFile( '/home/user/cookies.json', b4a.from(JSON.stringify({ 'stub.example': { x: 'y' } }), 'utf8') ) ctx.httpFetch = async (_url, init) => { curlCookieInit = init return new Response('c', { status: 200 }) } await runBinCommand(ctx, [ 'curl', '-b', '/home/user/cookies.json', 'https://stub.example/cookie-file' ]) t.is(ctx.exitCode, 0) t.ok(String(headerFromInit(curlCookieInit, 'Cookie')).includes('x=y')) lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async () => new Response('z', { status: 200, headers: { 'Set-Cookie': 'sess=hello; Path=/' } }) await runBinCommand(ctx, [ 'curl', '-c', '/home/user/jar.json', 'https://stub.example/jar' ]) t.is(ctx.exitCode, 0) const jraw = await ctx.vfs.readFile('/home/user/jar.json') t.ok(jraw && ctx.b4a.toString(jraw).includes('sess')) lines.length = 0 ctx.exitCode = 0 /** @type {{ insecure?: boolean, caPem?: string } | null} */ let curlTlsSeen = null ctx.httpFetch = async (_url, init) => { curlTlsSeen = init && init.bareOsCurlTls return new Response('z', { status: 200 }) } await runBinCommand(ctx, ['curl', '-k', 'https://stub.example/insecure']) t.is(ctx.exitCode, 0) t.ok(curlTlsSeen && curlTlsSeen.insecure === true) t.is(lines[0], 'z') lines.length = 0 ctx.exitCode = 0 await ctx.vfs.writeFile( '/home/user/ca-test.pem', b4a.from('-----BEGIN CERTIFICATE-----\nTEST\n-----END CERTIFICATE-----\n') ) let cacertInit = null ctx.httpFetch = async (_url, init) => { cacertInit = init && init.bareOsCurlTls return new Response('pem-ok', { status: 200 }) } await runBinCommand(ctx, [ 'curl', '--cacert', '/home/user/ca-test.pem', 'https://stub.example/ca' ]) t.is(ctx.exitCode, 0) t.ok( cacertInit && typeof cacertInit.caPem === 'string' && cacertInit.caPem.includes('BEGIN CERTIFICATE') ) t.is(lines[0], 'pem-ok') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('curl --connect-timeout aborts hanging stub fetch', async (t) => { const dir = testCorestoreDir('curlcto') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pccto')) await drive.ready() await personal.ready() const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log() {}, error() {} } ctx.httpFetch = async (_url, init) => new Promise((_resolve, reject) => { const sig = init && init.signal if (sig && sig.aborted) { reject(new Error('The operation was aborted')) return } if (sig) { sig.addEventListener('abort', () => reject(new Error('The operation was aborted')) ) } }) await runBinCommand(ctx, [ 'curl', '--connect-timeout', '1', 'https://stub.example/hang' ]) t.is(ctx.exitCode, 7) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('wget delegated from booter with stub fetch', async (t) => { const dir = testCorestoreDir('wget') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pwget')) await drive.ready() await personal.ready() const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error(s) { lines.push('e:' + String(s)) } } /** @type {RequestInit | undefined} */ let wgetInitPayload ctx.httpFetch = async (_url, init) => { wgetInitPayload = init return new Response('payload', { status: 200, headers: { 'Content-Type': 'text/plain' } }) } await runBinCommand(ctx, [ 'wget', '-O', 'saved.txt', '-q', 'https://stub.example/a' ]) t.is(ctx.exitCode, 0) t.is(headerFromInit(wgetInitPayload, 'User-Agent'), DEFAULT_WGET_USER_AGENT) const out = await ctx.vfs.readFile('saved.txt') t.ok(out) t.is(ctx.b4a.toString(out), 'payload') lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async () => new Response('', { status: 500 }) await runBinCommand(ctx, ['wget', '-q', 'https://stub.example/err']) t.is(ctx.exitCode, 8) lines.length = 0 ctx.exitCode = 0 ctx.httpFetch = async () => new Response('stdout-body', { status: 200 }) await runBinCommand(ctx, ['wget', '-O', '-', '-q', 'https://stub.example/b']) t.is(ctx.exitCode, 0) t.is(lines[0], 'stdout-body') lines.length = 0 ctx.exitCode = 0 let wgetSeenUrl = '' ctx.httpFetch = async (url) => { wgetSeenUrl = String(url) return new Response('p2', { status: 200, headers: { 'Content-Type': 'text/plain' } }) } await runBinCommand(ctx, ['wget', 'stub.example/z', '-qO', 'w2.txt']) t.is(ctx.exitCode, 0) t.is(wgetSeenUrl, 'http://stub.example/z') const w2 = await ctx.vfs.readFile('w2.txt') t.ok(w2) t.is(ctx.b4a.toString(w2), 'p2') lines.length = 0 ctx.exitCode = 0 /** @type {RequestInit | undefined} */ let wgetInitU ctx.httpFetch = async (_url, init) => { wgetInitU = init return new Response('u', { status: 200 }) } await runBinCommand(ctx, [ 'wget', '-q', '-U', 'WgetCustom/1', '-O', 'u.txt', 'https://stub.example/u' ]) t.is(ctx.exitCode, 0) t.is(headerFromInit(wgetInitU, 'User-Agent'), 'WgetCustom/1') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['wget', '-c', '-O', '-', 'https://stub.example/n']) t.is(ctx.exitCode, 2) lines.length = 0 ctx.exitCode = 0 await ctx.vfs.writeFile('partial.bin', b4a.from('ab')) ctx.httpFetch = async (_url, init) => { t.is(headerFromInit(init, 'Range'), 'bytes=2-') return new Response('cde', { status: 206, headers: { 'Content-Type': 'application/octet-stream' } }) } await runBinCommand(ctx, [ 'wget', '-q', '-c', '-O', 'partial.bin', 'https://stub.example/resume' ]) t.is(ctx.exitCode, 0) const merged = await ctx.vfs.readFile('partial.bin') t.is(ctx.b4a.toString(merged), 'abcde') lines.length = 0 ctx.exitCode = 0 await ctx.vfs.writeFile('part.txt', b4a.from('ab')) ctx.httpFetch = async (_url, init) => { t.is(headerFromInit(init, 'Range'), 'bytes=2-') return new Response('cd', { status: 206 }) } await runBinCommand(ctx, ['wget', '-qc', 'http://stub.example/blob/part.txt']) t.is(ctx.exitCode, 0) const partMerged = await ctx.vfs.readFile('part.txt') t.is(ctx.b4a.toString(partMerged), 'abcd') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('tier-1 rm -rf removes directory tree on personal drive', async (t) => { const dir = testCorestoreDir('rmrf') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('prm')) await drive.ready() await personal.ready() await drive.put('/bin/rm', b4a.from(await readBuiltBin('rm'))) const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log() {}, error() {} } await personal.put( personalHomeBacking('/home/user', 'nest/leaf/x.txt'), b4a.from('x') ) await personal.put( personalHomeBacking('/home/user', 'nest/other/y.txt'), b4a.from('y') ) t.ok((await ctx.vfs.readdir('nest')).includes('leaf')) await runBinCommand(ctx, ['rm', '-rf', 'nest']) t.is(ctx.exitCode, 0) const after = await ctx.vfs.readdir('.') t.ok(!after.includes('nest')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('git-fs-adapter mkdir recursive and readdir hides .bareos_empty', async (t) => { const dir = testCorestoreDir('gitfs') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pgf')) await drive.ready() await personal.ready() const ctx = testCtx(drive, personal) const fs = createGitFsFromVfs(ctx.vfs) const base = '/home/user/gittest' await fs.promises.mkdir(path.posix.join(base, 'a', 'b'), { recursive: true }) const inA = await fs.promises.readdir(path.posix.join(base, 'a')) t.is(inA.indexOf('.bareos_empty'), -1) t.ok(inA.includes('b')) const top = await fs.promises.readdir(base) t.ok(top.includes('a')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand delegates git to booter (ignores /bin/git script body)', async (t) => { const dir = testCorestoreDir('gitdel') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pgd')) await drive.ready() await personal.ready() await drive.put( '/bin/git', b4a.from( `async function run() { throw new Error('eval git should not run') }` ) ) const logs = [] const ctx = testCtx(drive, personal) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } await runBinCommand(ctx, ['git', 'version']) t.ok(logs.some((l) => /isomorphic-git/i.test(l))) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runBinCommand runs ./git from cwd instead of booter delegate', async (t) => { const dir = testCorestoreDir('gitlocal') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pgl')) await drive.ready() await personal.ready() await personal.put( personalHomeBacking('/home/user', 'git'), b4a.from(` async function run(ctx) { ctx.out.push('local-git-script') } `) ) const out = [] const ctx = testCtx(drive, personal) ctx.out = out await runBinCommand(ctx, ['./git']) t.is(out[0], 'local-git-script') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('runGitCli init and status on personal drive', async (t) => { const dir = testCorestoreDir('gitcmd') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pgc')) await drive.ready() await personal.ready() const logs = [] const ctx = testCtx(drive, personal) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } await runGitCli(ctx, ['git', 'init', '-C', '/home/user/myrepo']) t.ok(logs.some((l) => /initialized|git repository/i.test(l))) logs.length = 0 await runGitCli(ctx, ['git', '-C', '/home/user/myrepo', 'status']) t.ok(logs.length > 0) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('git clean -fd removes untracked files only', async (t) => { const dir = testCorestoreDir('gitclean') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pgcl')) await drive.ready() await personal.ready() const ctx = testCtx(drive, personal) ctx.console = { log() {}, error() {} } await runGitCli(ctx, ['git', 'init', '-C', '/home/user/clrepo']) await ctx.vfs.writeFile('/home/user/clrepo/a.txt', b4a.from('a')) await runGitCli(ctx, ['git', '-C', '/home/user/clrepo', 'add', 'a.txt']) await runGitCli(ctx, [ 'git', '-C', '/home/user/clrepo', 'commit', '-m', 'init' ]) await ctx.vfs.writeFile('/home/user/clrepo/junk.txt', b4a.from('j')) await runGitCli(ctx, ['git', '-C', '/home/user/clrepo', 'clean', '-fd']) t.is(await ctx.vfs.readFile('/home/user/clrepo/junk.txt'), null) t.ok(await ctx.vfs.readFile('/home/user/clrepo/a.txt')) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('curl -O -J saves Content-Disposition filename', async (t) => { const dir = testCorestoreDir('curlj') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pcj')) await drive.ready() await personal.ready() const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.httpFetch = async () => new Response(b4a.from('payload'), { status: 200, headers: { 'Content-Disposition': 'attachment; filename="from-server.bin"' } }) await runBinCommand(ctx, [ 'curl', '-s', '-O', '-J', 'https://stub.example/blob' ]) t.is(ctx.exitCode, 0) const out = await ctx.vfs.readFile('/home/user/from-server.bin') t.ok(out) t.is(ctx.b4a.toString(out), 'payload') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('bare-os-ipc fanout publishes to subscribers', async (t) => { const ipc = createBareOsIpc({ maxFifoBytes: 65536 }) const a = ipc.fanoutSubscribe('news') const b = ipc.fanoutSubscribe('news') ipc.fanoutPublish('news', b4a.from('x', 'utf8')) t.is(b4a.toString(await a.take()), 'x') t.is(b4a.toString(await b.take()), 'x') a.dispose() b.dispose() }) test('bare-os-ipc pushJson requires token when configured', async (t) => { const ipc = createBareOsIpc({ ipcRpcToken: 'secret' }) ipc.create('q') t.exception(() => ipc.pushJson('q', { x: 1 }), /token/) ipc.pushJson('q', { x: 1, bareOsIpcToken: 'secret' }) const j = await ipc.takeJson('q') t.is(j.x, 1) }) test('bareOsHttpUrlAllowed allowlist and denylist', async (t) => { t.ok(bareOsHttpUrlAllowed('https://a.example/x', { allow: [], deny: [] }).ok) t.ok( !bareOsHttpUrlAllowed('https://evil.com/', { allow: ['a.example'], deny: [] }).ok ) t.ok( bareOsHttpUrlAllowed('https://a.example/', { allow: ['a.example'], deny: [] }).ok ) t.ok( !bareOsHttpUrlAllowed('https://a.example/', { allow: ['a.example'], deny: ['a.example'] }).ok ) }) test('raceWithAbortAndTimeout rejects on timeout', async (t) => { try { await raceWithAbortAndTimeout( new Promise(() => {}), { timeoutMs: 30 }, 'hang' ) t.ok(false, 'expected timeout') } catch (e) { t.ok(/timed out/.test(String(e && e.message))) } }) test('kernel share/man/man.json page count matches coreutils + extras + handbook + devguide', async (t) => { const manPath = path.join(__dirname, '../../kernel/share/man/man.json') const raw = JSON.parse(await readFile(manPath, 'utf8')) const { COREUTILS_COMMANDS, MAN_EXTRA_PAGES } = await import('../bare-os-coreutils/lib/commands.mjs') const handbookDir = path.join(__dirname, '../../handbook') const devguideDir = path.join(__dirname, '../../developer-guide') const handbookMd = (await readdir(handbookDir)).filter((f) => f.endsWith('.md') ).length const devguideMd = (await readdir(devguideDir)).filter((f) => f.endsWith('.md') ).length t.is( raw.pages.length, COREUTILS_COMMANDS.length + MAN_EXTRA_PAGES.length + handbookMd + devguideMd ) t.ok(Array.isArray(raw.apropos) && raw.apropos.length > 0) t.is(typeof raw.index.ls, 'number') t.is(typeof raw.index.handbook, 'number') t.is(typeof raw.index.devguide, 'number') const hb = raw.pages[raw.index.handbook] t.is(hb.section, 7) t.is(hb.name, 'bare-os-handbook') const dg = raw.pages[raw.index.devguide] t.is(dg.section, 7) t.is(dg.name, 'bare-os-developer-guide') }) test('runBinCommand man ls prints manual text', async (t) => { const dir = testCorestoreDir('mann') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pmn')) await drive.ready() await personal.ready() const manPath = path.join(__dirname, '../../kernel/share/man/man.json') await drive.put( '/share/man/man.json', b4a.from(await readFile(manPath, 'utf8')) ) await drive.put('/bin/man', b4a.from(await readBuiltBin('man'))) const logs = [] const ctx = testCtx(drive, personal) ctx.console = { log: (...a) => logs.push(a.join(' ')), error: (...a) => logs.push(a.join(' ')) } ctx.exitCode = 0 await runBinCommand(ctx, ['man', 'ls']) t.is(ctx.exitCode, 0) const text = logs.join('\n') t.ok(text.includes('SYNOPSIS')) t.ok(text.includes('EXAMPLES')) t.ok(text.includes('ls')) logs.length = 0 await runBinCommand(ctx, ['man', '-w']) t.is(ctx.exitCode, 0) t.is(logs.join('\n').trim(), '/share/man/man.json') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('coreutils sed and awk fixture corpus', async (t) => { const corpusPath = path.join( __dirname, '../bare-os-coreutils/fixtures/sed-awk-corpus.json' ) const corpus = JSON.parse(await readFile(corpusPath, 'utf8')) const dir = testCorestoreDir('sedawkcorpus') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psac')) await drive.ready() await personal.ready() await drive.put('/bin/sed', b4a.from(await readBuiltBin('sed'))) await drive.put('/bin/awk', b4a.from(await readBuiltBin('awk'))) const lines = [] const ctx = testCtx(drive, personal) ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error(...a) { lines.push(a.join(' ')) } } function corpusNormLines(logs) { return logs .flatMap((l) => String(l).split('\n')) .filter((x) => x.length > 0) } for (const c of corpus.sed) { await ctx.vfs.writeFile(c.file, b4a.from(c.content)) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, c.argv) t.is(ctx.exitCode, 0, 'sed ' + c.name) t.alike(corpusNormLines(lines), c.lines, 'sed ' + c.name) } for (const c of corpus.awk) { if (c.progFile) { await ctx.vfs.writeFile(c.progFile, b4a.from(c.progContent)) } if (c.file) await ctx.vfs.writeFile(c.file, b4a.from(c.content)) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, c.argv) t.is(ctx.exitCode, 0, 'awk ' + c.name) t.alike(corpusNormLines(lines), c.lines, 'awk ' + c.name) } await store.close() rmSync(dir, { recursive: true, force: true }) }) test('coreutils matrix: cp find sort printf uniq realpath sha256sum base64 rm -d', async (t) => { const dir = testCorestoreDir('corematrix') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pcm')) await drive.ready() await personal.ready() const bins = [ 'cp', 'find', 'sort', 'printf', 'uniq', 'realpath', 'sha256sum', 'base64', 'rm', 'mkdir', 'touch' ] for (const b of bins) { await drive.put('/bin/' + b, b4a.from(await readBuiltBin(b))) } await drive.put( '/bin/_corpus_echo', b4a.from(`async function run(ctx, argv) { ctx.console.log(argv.slice(1).join(' ')) } `) ) const lines = [] const ctx = testCtx(drive, personal) ctx.runBinCommand = function (argv, ro) { return runBinCommand(this, argv, ro) } ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error(...a) { lines.push(a.join(' ')) } } await ctx.vfs.mkdir('tree', { recursive: true }) await ctx.vfs.writeFile('tree/a.txt', b4a.from('newdata')) await ctx.vfs.writeFile('dest.txt', b4a.from('stale')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['touch', '-d', '@1', 'dest.txt']) t.is(ctx.exitCode, 0) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['touch', '-d', '@100000', 'tree/a.txt']) t.is(ctx.exitCode, 0) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['cp', '-u', 'tree/a.txt', 'dest.txt']) t.is(ctx.exitCode, 0, 'cp -u') t.is(ctx.b4a.toString(await ctx.vfs.readFile('dest.txt')), 'newdata') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['find', '.', '-type', 'f', '-regex', '.*\\.txt$']) t.is(ctx.exitCode, 0, 'find -regex') t.ok(lines.some((l) => String(l).includes('a.txt'))) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['find', 'tree', '-exec', '_corpus_echo', '{}', ';']) t.is(ctx.exitCode, 0, 'find -exec') t.ok(lines.some((l) => /a\.txt/.test(String(l)))) lines.length = 0 ctx.exitCode = 0 ctx.shellStdin = '3\n1\n2\n' await runBinCommand(ctx, ['sort', '-n']) t.is(lines.join('\n'), '1\n2\n3') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['printf', '%s-%d', 'n', '7']) t.is(lines[0], 'n-7') await ctx.vfs.writeFile('u.txt', b4a.from('a\na\nb\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['uniq', '-c', 'u.txt']) t.ok(lines.some((l) => /^\s*2\s+a$/.test(String(l)))) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['realpath', 'tree/a.txt']) t.ok(/a\.txt$/.test(lines[0])) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sha256sum', 'u.txt']) t.is(lines.length, 1) t.ok(/^[a-f0-9]{64}\s+/.test(lines[0])) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['base64', '-w', '0', 'u.txt']) const dec = Buffer.from( lines.join('').replace(/\s+/g, ''), 'base64' ).toString() t.is(dec, 'a\na\nb\n') await ctx.vfs.mkdir('emptydir', { recursive: true }) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['rm', '-d', 'emptydir']) t.is(ctx.exitCode, 0, 'rm -d') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('coreutils gnu-gap batch: paste tac rev md5sum expr tsort numfmt truncate install comm join', async (t) => { const dir = testCorestoreDir('gnugap') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('ngg')) await drive.ready() await personal.ready() const bins = [ 'paste', 'tac', 'rev', 'md5sum', 'expr', 'tsort', 'numfmt', 'sync', 'truncate', 'install', 'unlink', 'comm', 'join', 'yes', 'cp', 'touch', 'mkdir', 'ls' ] for (const b of bins) { await drive.put('/bin/' + b, b4a.from(await readBuiltBin(b))) } const lines = [] const ctx = testCtx(drive, personal) ctx.runBinCommand = function (argv, ro) { return runBinCommand(this, argv, ro) } ctx.exitCode = 0 ctx.console = { log(s) { lines.push(String(s)) }, error(...a) { lines.push(a.join(' ')) } } ctx.vfs.env.BARE_OS_YES_MAX_LINES = '2' lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['yes', 'ok']) t.is(ctx.exitCode, 0) t.is(lines.filter((l) => l === 'ok').length, 2) await ctx.vfs.writeFile('nums.txt', b4a.from('1\n2\n3\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['tac', 'nums.txt']) t.is(lines.join('\n'), '3\n2\n1') await ctx.vfs.writeFile('rv.txt', b4a.from('ab\ncd\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['rev', 'rv.txt']) t.is(lines.join('\n'), 'ba\ndc') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['md5sum', 'nums.txt']) t.ok(/^[a-f0-9]{32}\s/.test(lines[0])) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['expr', '1', '+', '2', '*', '3']) t.is(lines[0], '7') await ctx.vfs.writeFile('ts.txt', b4a.from('a b\nb c\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['tsort', 'ts.txt']) t.is(lines.join('\n'), 'a\nb\nc') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['numfmt', '--to=iec', '1024']) t.is(lines[0], '1K') lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['sync']) t.is(ctx.exitCode, 0) await ctx.vfs.writeFile('tr.txt', b4a.from('hello')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['truncate', '-s', '2', 'tr.txt']) t.is(ctx.exitCode, 0) t.is(ctx.b4a.toString(await ctx.vfs.readFile('tr.txt')), 'he') await ctx.vfs.writeFile('src.txt', b4a.from('data')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['install', '-m', '600', 'src.txt', 'dest.txt']) t.is(ctx.exitCode, 0) t.is(ctx.b4a.toString(await ctx.vfs.readFile('dest.txt')), 'data') await ctx.vfs.writeFile('s1.txt', b4a.from('a\nb\n')) await ctx.vfs.writeFile('s2.txt', b4a.from('a\nc\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['comm', 's1.txt', 's2.txt']) t.ok(lines.some((l) => l.includes('\t\ta'))) await ctx.vfs.writeFile('j1.txt', b4a.from('1 x\n2 y\n')) await ctx.vfs.writeFile('j2.txt', b4a.from('1 p\n2 q\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['join', 'j1.txt', 'j2.txt']) t.ok(lines.some((l) => /1\s+x\s+1\s+p/.test(String(l)))) await ctx.vfs.writeFile('u.txt', b4a.from('x')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['unlink', 'u.txt']) t.is(ctx.exitCode, 0) t.is(await ctx.vfs.readFile('u.txt'), null) await ctx.vfs.writeFile('p1.txt', b4a.from('a\nb\n')) await ctx.vfs.writeFile('p2.txt', b4a.from('1\n2\n')) lines.length = 0 ctx.exitCode = 0 await runBinCommand(ctx, ['paste', 'p1.txt', 'p2.txt']) t.is(lines[0], 'a\t1') t.is(lines[1], 'b\t2') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('verifyBootManifestEd25519 rejects invalid inputs', async (t) => { const { verifyBootManifestEd25519 } = await import('#bare-os-boot-manifest-sig') const msg = b4a.from('manifest-bytes', 'utf8') t.absent(verifyBootManifestEd25519(msg, null, '')) t.absent(verifyBootManifestEd25519(msg, msg, '00ff')) const z64 = '0'.repeat(64) t.absent(verifyBootManifestEd25519(msg, new Uint8Array(64), z64)) }) test('bareOsIpc.duplexJsonRoundTrip', async (t) => { const ipc = createBareOsIpc() const { left, right } = ipc.createDuplexBridge('dupjx') const respP = ipc.duplexJsonRoundTrip(right, { id: 7, method: 'ping' }) const u8 = await left.take() const req = JSON.parse(b4a.toString(u8, 'utf8')) t.is(req.method, 'ping') left.push( b4a.from( JSON.stringify({ bareOsRpc: '2', id: 7, result: 'pong' }) + '\n', 'utf8' ) ) const out = await respP t.is(out.result, 'pong') }) test('unit journal exposed under /run/bare-os/unit-journal', async (t) => { const { appendBareInitdJournal, clearBareInitdJournalForTests, getBareInitdJournalNdjson } = await import('./lib/bare-initd-journal.js') clearBareInitdJournalForTests() appendBareInitdJournal('demo', { event: 'unit_test' }) const dir = testCorestoreDir('vj') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pvj')) await sys.ready() await personal.ready() const env = { HOME: '/home/guest', PWD: '/home/guest', PATH: '/bin', USER: 'guest' } const vfs = createVfs(sys, personal, env, null, { getUnitJournalNdjson: (u) => getBareInitdJournalNdjson(u) }) t.ok((await vfs.readdir('/run/bare-os/unit-journal')).includes('demo.ndjson')) const j = b4a.toString( await vfs.readFile('/run/bare-os/unit-journal/demo.ndjson') ) t.ok(j.includes('unit_test')) clearBareInitdJournalForTests() await store.close() rmSync(dir, { recursive: true, force: true }) }) test('worker_budget proc surface schema 2 exposes cpu and class map env', async (t) => { const j = buildBareOsReplicationOperatorSurfaceProcJson('worker_budget', { BARE_OS_BIN_WORKER_WALL_MS_MAX: '5000', BARE_OS_BIN_WORKER_CPU_MS_MAX: '2500', BARE_OS_KERNEL_RUNNER_CLASS_CPU_MS_MAX_JSON: '{"textproc":100}' }) t.is(j.schema, 2) t.is(j.wallMsMax, '5000') t.is(j.cpuMsMax, '2500') t.alike(j.kernelRunnerClassCpuMsMax, { textproc: 100 }) }) test('process table snapshot includes processGroups metadata', async (t) => { const s = bareOsProcessTableSnapshot({ env: { BARE_OS_SHELL_PIPEFAIL: '1' } }) t.ok(s.processGroups) t.is(s.processGroups.schema, 1) t.ok(String(s.processGroups.killpgAnalog).includes('killpg')) t.is(s.schemaVersion, 7) t.ok(s.jobControlSemantics && s.jobControlSemantics.pipefail === true) const booter = s.processes.find((p) => p && p.pid === 2) t.ok(booter && booter.parentName === 'bare-os-kernel') const shell = s.processes.find((p) => p && p.pid === 3) t.ok(shell && shell.parentName === 'bare-os-booter') t.ok(s.signalRouting && s.signalRouting.schema === 1) t.ok(s.initdBinding) t.ok(s.signalModel && Array.isArray(s.signalModel.sigpendingAnalog)) t.ok(s.exitStatusModel && s.exitStatusModel.schema === 1) }) test('bare_acl other:: and mask interact like POSIX ACL classes', async (t) => { const env = { UID: '1000', GID: '1000' } const p1 = bareOsParseBareAclText('other::---\n') t.ok(bareOsAclDeniesSubject(p1, env, '1000', '1000', 'read')) const p2 = bareOsParseBareAclText( 'user:1000:rwx\nmask::r--\nother::rwx\n' ) t.ok(bareOsAclDeniesSubject(p2, env, '1000', '1000', 'write')) t.absent(bareOsAclDeniesSubject(p2, env, '1000', '1000', 'read')) const p3 = bareOsParseBareAclText('user::r-x\n') t.ok(bareOsAclDeniesSubject(p3, env, '1000', '1000', 'write')) t.absent(bareOsAclDeniesSubject(p3, env, '1000', '1000', 'read')) }) test('buildBareOsReplicationOperatorSurfaceProcJson corestore_snapshot', async (t) => { const j = buildBareOsReplicationOperatorSurfaceProcJson('corestore_snapshot', { BARE_OS_SEED_CORESTORE_SNAPSHOT_TAG: 'ci-tag', BARE_OS_SEED_SNAPSHOT_HINTS_JSON: '{"ok":true}', BARE_OS_CORESTORE_SNAPSHOT_STATE_JSON: '{"cores":3,"paused":false}', BARE_OS_CORESTORE_SNAPSHOT_PAUSED: '1', BARE_OS_REPLICATION_PAUSED: 'true' }) t.is(j.schema, 2) t.is(j.snapshotTag, 'ci-tag') t.ok(j.snapshotHintsJson && j.snapshotHintsJson.ok === true) t.is(j.operatorSnapshotState?.cores, 3) t.is(j.paused, true) t.is(j.replicationPausedEnv, true) }) test('buildBareOsReplicationOperatorSurfaceProcJson replication_operator_panel', async (t) => { const j = buildBareOsReplicationOperatorSurfaceProcJson( 'replication_operator_panel', { BARE_OS_REPLICATION_OPERATOR_PANEL_JSON: '{"treeLength":42}', BARE_OS_HYPERCORE_LENGTHS_JSON: '{"a":1}', BARE_OS_REPLICATION_BACKPRESSURE_JSON: '{"depth":1}', BARE_OS_DHT_STATUS_JSON: '{"ok":true}', BARE_OS_PEER_ALLOWLIST_HEX: 'abc' } ) t.is(j.schema, 1) t.ok(j.panel && j.panel.treeLength === 42) t.ok(j.hypercoreLengths && j.hypercoreLengths.a === 1) t.is(j.peerAllowlistHexConfigured, true) }) test('bare-os-protocol swarm topic matches PROTOCOL_NAME', async (t) => { const { PROTOCOL_NAME, TOPIC_STRING, topicKey } = await import( 'bare-os-protocol' ) t.is(PROTOCOL_NAME, TOPIC_STRING) t.is(PROTOCOL_NAME, 'bare-os-v1') const k = topicKey() t.is(k.length, 32) }) test('bareOsIpc.stats includes ipcBackpressure topChannels', async (t) => { const ipc = createBareOsIpc() ipc.create('q1') const u8 = b4a.from('x') for (let i = 0; i < 5; i++) ipc.push('q1', u8) const st = ipc.stats() t.ok(st.ipcBackpressure && st.ipcBackpressure.schema === 1) t.ok(Array.isArray(st.ipcBackpressure.topChannels)) t.ok(st.ipcBackpressure.topChannels.some((r) => r.name === 'q1')) }) test('bareOsWasmKernelCompile bounds and compile path', async (t) => { const { bareOsWasmKernelCompile } = await import('./lib/bare-os-wasm-kernel.js') const big = new Uint8Array(600 * 1024) const r0 = await bareOsWasmKernelCompile(big, { maxBytes: 1024 }) t.absent(r0.ok) if (typeof WebAssembly === 'undefined' || !WebAssembly.compile) { const r1 = await bareOsWasmKernelCompile(new Uint8Array([0x00, 0x61, 0x73, 0x6d])) t.absent(r1.ok) return } const minimal = new Uint8Array([ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00 ]) const r2 = await bareOsWasmKernelCompile(minimal) t.ok(r2.ok === true || r2.ok === false) }) test('bareOsWasmKernelInstantiate exposes wall clock import with syscall imports', async (t) => { const { bareOsWasmKernelInstantiate } = await import('./lib/bare-os-wasm-kernel.js') if (typeof WebAssembly === 'undefined' || !WebAssembly.compile) { t.pass('skip: no WebAssembly') return } const wasmMinimal = new Uint8Array([ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00 ]) const ctx = { bareOsPathconf: () => '4096' } const r = await bareOsWasmKernelInstantiate(wasmMinimal, ctx, { wasmSyscallImports: true, shellEnv: { BARE_OS_WASM_KERNEL_SYSCALL: '1' } }) if (!r.ok) { t.pass('instantiate may fail on minimal module; wall import path exercised when ok') return } t.ok(r.wasmWallClockMs32Import) t.ok(r.wasmPathconfImport) }) test('bareOsAppendVaultRotationCheckpoint appends vault_save row', async (t) => { const { bareOsAppendVaultRotationCheckpoint } = await import( './lib/bare-os-vault-rotation-audit.js' ) /** @type {{ p: string, buf: Uint8Array }[]} */ const puts = [] const drive = { async get(p) { if (p === '/.bare/vault-rotation-audit.ndjson') return null return null }, async put(p, buf) { puts.push({ p, buf: buf instanceof Uint8Array ? buf : b4a.from(buf) }) } } const ctx = { personalDrive: drive } await bareOsAppendVaultRotationCheckpoint(ctx, { kind: 'vault_save', fileCount: 2 }) const auditPut = puts.filter((x) => x.p === '/.bare/vault-rotation-audit.ndjson') t.is(auditPut.length, 1) const last = JSON.parse(b4a.toString(auditPut[0].buf).trim()) t.is(last.kind, 'vault_save') t.is(last.fileCount, 2) }) test('protomux and hyperswarm versions match repo lock contract', async (t) => { const { readFileSync } = await import('node:fs') const lockPath = path.join(__dirname, '../../package-lock.json') const lock = JSON.parse(readFileSync(lockPath, 'utf8')) const pm = lock.packages?.['node_modules/protomux']?.version const hs = lock.packages?.['node_modules/hyperswarm']?.version t.ok(pm && hs) const snapPath = path.join(__dirname, 'fixtures/protomux-hyperswarm-lock.json') const snap = JSON.parse(readFileSync(snapPath, 'utf8')) t.is(pm, snap.protomux) t.is(hs, snap.hyperswarm) }) test('kernel extension topological order matches guest Kahn tie-break', async (t) => { const entries = [ { file: 'b.json', extId: 'b', scripts: ['/x'], dependsOn: ['a'] }, { file: 'a.json', extId: 'a', scripts: ['/y'], dependsOn: [] } ] const topo = topologicalOrderKernelExtensions(entries) t.ok(topo.ok) t.is( topo.ordered.map((e) => e.file).join(','), 'a.json,b.json', 'filename order breaks ties; dependsOn edge b→a' ) }) test('kernel extension resolver detects dependency cycle', async (t) => { const entries = [ { file: 'a.json', extId: 'a', scripts: ['/x'], dependsOn: ['b'] }, { file: 'b.json', extId: 'b', scripts: ['/y'], dependsOn: ['a'] } ] const topo = topologicalOrderKernelExtensions(entries) t.absent(topo.ok) t.ok( /** @type {{ cycleExtIds: string[] }} */ (topo).cycleExtIds.length >= 2 ) }) test('protomux alias registry snapshot matches proc wire contract shape', async (t) => { const reg = createBareOsProtomuxAliasRegistry() reg.register('guestChannel', 'wireChannel') const rt = reg.snapshot() t.is(rt.schema, 2) t.is(rt.aliases.guestChannel, 'wireChannel') t.ok(Array.isArray(rt.changeLogTail)) t.ok(rt.reverseIndex && typeof rt.reverseIndex === 'object') }) test('createBareOsIpc enforces maxChannels quota', async (t) => { const ipc = createBareOsIpc({ maxChannels: 2, maxFifoBytes: 4096 }) ipc.create('a') ipc.create('b') let threw = false try { ipc.create('c') } catch { threw = true } t.ok(threw) const st = ipc.stats() t.is(st.maxChannels, 2) t.ok(st.telemetry.fifoCreateDeniedQuota >= 1) }) test('vfs union write deny + bareOsEvictWarmReadLogicalPath selective eviction', async (t) => { const dir = testCorestoreDir('unionvfs') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('uv')) await sys.ready() await personal.ready() await sys.put('/bin/u1', b4a.from('a')) await sys.put('/bin/u2', b4a.from('b')) const warmRef = { current: null } const env = { HOME: '/home/g', PWD: '/', PATH: '/bin', BARE_OS_VFS_BIN_CACHE: '1' } const vfs = createVfs(sys, personal, env, null, { unionReadPrefixes: ['/bin'], unionWriteDenyPrefixes: ['/bin'], warmReadCacheStatsRef: warmRef }) let denied = false try { await vfs.writeFile('/bin/z', b4a.from('x')) } catch { denied = true } t.ok(denied, 'union write deny blocks /bin write') await vfs.readFile('/bin/u1') await vfs.readFile('/bin/u2') const hits = warmRef.current?.hits ?? 0 vfs.bareOsEvictWarmReadLogicalPath('/bin/u1') const m0 = warmRef.current?.misses ?? 0 await vfs.readFile('/bin/u1') t.ok((warmRef.current?.misses ?? 0) > m0, 'u1 evicted') const hitsU2 = warmRef.current?.hits ?? 0 await vfs.readFile('/bin/u2') t.ok((warmRef.current?.hits ?? 0) > hitsU2, 'u2 still warm') await store.close() rmSync(dir, { recursive: true, force: true }) }) test('disk.os replication_operator_sketch mirrors blind v3 and hyperblobs env JSON', async (t) => { const dir = testCorestoreDir('diskosenv') const store = new Corestore(dir) const drive = new Hyperdrive(store) await drive.ready() const prevB = process.env.BARE_OS_BLIND_PEER_TOPOLOGY_V3_JSON const prevH = process.env.BARE_OS_HYPERBLOBS_STATS_JSON process.env.BARE_OS_BLIND_PEER_TOPOLOGY_V3_JSON = JSON.stringify({ schema: 3, hint: 't' }) process.env.BARE_OS_HYPERBLOBS_STATS_JSON = JSON.stringify({ chunkCount: 4 }) try { const bridge = createBareOsDiskOsBridge({ drive, bareOsIpc: { list: () => [] }, ctxApiVersion: BARE_OS_CTX_API_VERSION, systemRevision: null, bootStartedMs: Date.now() }) const op = await bridge.execRpc('bare_os', 'replication_operator_sketch', []) const oj = JSON.parse(op) t.is(oj.schema, 4) t.is(oj.blindTopologySketchV3?.schema, 3) t.is(oj.hyperblobsDedupSketch?.chunkCount, 4) } finally { if (prevB === undefined) delete process.env.BARE_OS_BLIND_PEER_TOPOLOGY_V3_JSON else process.env.BARE_OS_BLIND_PEER_TOPOLOGY_V3_JSON = prevB if (prevH === undefined) delete process.env.BARE_OS_HYPERBLOBS_STATS_JSON else process.env.BARE_OS_HYPERBLOBS_STATS_JSON = prevH } await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ctx bareOsRunCurlCli works when host delegates curl is disabled', async (t) => { const dir = testCorestoreDir('curlctx') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('cc')) await sys.ready() await personal.ready() const ctx = testCtx(sys, personal, { BARE_OS_DELEGATE_ALLOW: 'git', HOME: '/home/g', PWD: '/', PATH: '/bin' }) let ran = false ctx.bareOsRunCurlCli = async () => { ran = true } const curlSrc = await readFile( path.join(__dirname, '../../kernel/bin/curl'), 'utf8' ) await sys.put('/bin/curl', b4a.from(curlSrc)) await runBinCommand(ctx, ['curl', 'http://example.test/x']) t.ok(ran) await store.close() rmSync(dir, { recursive: true, force: true }) }) async function readBuiltBin(name) { const fs = await import('node:fs/promises') const p = path.join(__dirname, '../../kernel/bin', name) return fs.readFile(p, 'utf8') }