145 lines
4.1 KiB
JavaScript
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/bare-os-ipc.js'
|
|
import { createVfs } from './lib/vfs.js'
|
|
import { runBinCommand } from './lib/kernel-runner.js'
|
|
import { execShellLine, expandWord } from './lib/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 })
|
|
})
|