Files
bare-operating-system/packages/bare-os-booter/test.shell-bracket-smoke.mjs
T
2026-08-18 18:11:34 -04:00

145 lines
4.1 KiB
JavaScript

/**
* Focused smoke for `[` / `test` builtins and $(( $var … )) (avoids full test.js brittle/os.cwd failure path).
*/
import test from 'brittle'
import b4a from 'b4a'
import Hyperdrive from 'hyperdrive'
import Corestore from 'corestore'
import { mkdirSync, rmSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { readFile } from 'node:fs/promises'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
import { createBareOsIpc } from './lib/tools/bare-os-ipc.js'
import { createVfs } from './lib/vfs/vfs.js'
import { runBinCommand } from './lib/boot/kernel-runner.js'
import { execShellLine, expandWord } from './lib/shell/shell.js'
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',
BARE_OS_SSH_LISTEN_PORT: '0',
...env
}
const bareOsIpc = createBareOsIpc()
const vfs = createVfs(drive, personal, shellEnv, null, { bareOsIpc })
return {
drive,
personalDrive: personal,
vfs,
bareOsIpc,
env: shellEnv,
console,
b4a
}
}
async function readBuiltBin(name) {
const root = path.join(__dirname, '..', '..')
return readFile(path.join(root, 'kernel', 'bin', name), 'utf8')
}
test('execShellLine test [ builtins and $(( $var + … ))', async (t) => {
const dir = testCorestoreDir('shbracket-smoke')
const store = new Corestore(dir)
const drive = new Hyperdrive(store)
const personal = new Hyperdrive(store.namespace('pshbrk-sm'))
await drive.ready()
await personal.ready()
await drive.put('/bin/test', b4a.from(await readBuiltBin('test')))
const ctx = testCtx(drive, personal)
ctx.runBinCommand = function (argv, ro) {
return runBinCommand(this, argv, ro)
}
ctx.exitCode = 0
await execShellLine(ctx, 'a=1; test 2 -eq $((a+1))')
t.is(ctx.exitCode, 0)
ctx.exitCode = 0
await execShellLine(ctx, 'a=1; [ 2 -eq $(($a+1)) ]')
t.is(ctx.exitCode, 0)
await store.close()
rmSync(dir, { recursive: true, force: true })
})
test('expandWord arithmetic honors $var inside $(( ))', (t) => {
t.is(expandWord('$(( $a + 1 ))', { a: '2' }), '3')
t.is(expandWord('$(( $a+1 ))', { a: '2' }), '3')
})
test('execShellLine merges identity from child command context', async (t) => {
const dir = testCorestoreDir('shell-identity-merge')
const store = new Corestore(dir)
const drive = new Hyperdrive(store)
const personal = new Hyperdrive(store.namespace('psh-ident-merge'))
await drive.ready()
await personal.ready()
await drive.put(
'/bin/login',
b4a.from(`async function run(ctx) {
ctx.vfs.env.BARE_OS_IDENTITY = 'unlocked'
ctx.identity = {
state: 'unlocked',
publicKey: new Uint8Array(32),
secretKey: new Uint8Array(64)
}
ctx.console.log('Unlocked as test-user')
}
`)
)
await drive.put(
'/bin/savevault',
b4a.from(`async function run(ctx) {
if (!ctx.identity?.secretKey || ctx.identity.state !== 'unlocked') {
throw new Error('Not logged in')
}
ctx.console.log('Vault saved (0 files)')
}
`)
)
const lines = []
const errs = []
const ctx = testCtx(drive, personal)
ctx.console = {
log(...args) {
lines.push(args.map((a) => String(a)).join(' '))
},
error(...args) {
errs.push(args.map((a) => String(a)).join(' '))
}
}
ctx.identity = { state: 'guest', publicKey: null, secretKey: null }
ctx.runBinCommand = function (argv, ro) {
return runBinCommand(this, argv, ro)
}
await execShellLine(ctx, 'savevault')
t.ok(errs.includes('Not logged in'))
errs.length = 0
await execShellLine(ctx, 'login')
t.is(ctx.identity?.state, 'unlocked')
t.ok(ctx.identity?.secretKey instanceof Uint8Array)
await execShellLine(ctx, 'savevault')
t.alike(errs, [])
t.ok(lines.includes('Vault saved (0 files)'))
await store.close()
rmSync(dir, { recursive: true, force: true })
})