Files
bare-operating-system/packages/bare-os-booter/test.js
T
Raven Scott 6f923f72d1 Implement roadmap items across booter, protocol, kernel bundle, coreutils, and docs.
- Hyperswarm connection caps (env + /proc + disk.os replication_operator_sketch)
- Protomux operator metrics schema; warm-cache invalidation on replication
- ctx.bareOsSyscall nanosleep; socket bridge getsockopt/setsockopt (keepalive/nodelay)
- Extension signer pin verification before kernel.ext.d scripts; ctx/DTS updates
- Structured seeder logging (BARE_OS_SEED_LOG_*); release-checklist holepunch drift
- POSIX profile/matrix/conformance lists + handbook/env appendix/kernel-extensions
- Coreutils printf golden tests; sync kernel ↔ seeder parity after bundle
2026-04-05 02:38:24 -04:00

6497 lines
199 KiB
JavaScript

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,
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/<seg>/…` (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('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'))
})
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')
}