135 lines
4.1 KiB
JavaScript
135 lines
4.1 KiB
JavaScript
/**
|
|
* Minimal **`brittle-bare`** suite (no Node **`brittle-node`** / Hyperdrive session).
|
|
* Run: **`npm run test:bare -w bare-os-booter`** (concatenates **`test.identity.js`**).
|
|
*/
|
|
import test from 'brittle'
|
|
import b4a from 'b4a'
|
|
import crypto from 'hypercore-crypto'
|
|
import { buildMbr, parseMbr, topicKey, TOPIC_STRING, BLOCK_SIZE } from 'bare-os-protocol'
|
|
import { createBareOsDiskOsBridge } from './lib/host/bare-os-disk-os-bridge.js'
|
|
import { BARE_OS_CTX_API_VERSION } from './lib/ctx/bare-os-ctx-api.js'
|
|
|
|
function hostEnv() {
|
|
return globalThis.process && globalThis.process.env ? globalThis.process.env : null
|
|
}
|
|
|
|
test('disk.os replication_operator_intent EPERM when cap RPC off', async (t) => {
|
|
const bridge = createBareOsDiskOsBridge({
|
|
drive: null,
|
|
bareOsIpc: { list: () => [] },
|
|
ctxApiVersion: BARE_OS_CTX_API_VERSION,
|
|
systemRevision: null,
|
|
bootStartedMs: Date.now()
|
|
})
|
|
const env = hostEnv()
|
|
if (!env) {
|
|
t.pass('host env unavailable in this bare runtime')
|
|
return
|
|
}
|
|
const prev = env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC
|
|
if (prev !== undefined) delete env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC
|
|
try {
|
|
const raw = await bridge.execRpc(
|
|
'bare_os',
|
|
'replication_operator_intent',
|
|
['{}']
|
|
)
|
|
const j = JSON.parse(raw)
|
|
t.is(j.schema, 2)
|
|
t.is(j.ok, false)
|
|
t.is(j.code, 'EPERM')
|
|
} finally {
|
|
if (prev !== undefined) env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC = prev
|
|
}
|
|
})
|
|
|
|
test('disk.os replication_operator_intent ok when cap RPC on', async (t) => {
|
|
const audit = []
|
|
const bridge = createBareOsDiskOsBridge({
|
|
drive: null,
|
|
bareOsIpc: { list: () => [] },
|
|
ctxApiVersion: BARE_OS_CTX_API_VERSION,
|
|
systemRevision: null,
|
|
bootStartedMs: Date.now(),
|
|
auditBatch: (rows) => {
|
|
audit.push(...rows)
|
|
return rows.length
|
|
}
|
|
})
|
|
const env = hostEnv()
|
|
if (!env) {
|
|
t.pass('host env unavailable in this bare runtime')
|
|
return
|
|
}
|
|
const prev = env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC
|
|
env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC = '1'
|
|
try {
|
|
const raw = await bridge.execRpc(
|
|
'bare_os',
|
|
'replication_operator_intent',
|
|
[JSON.stringify({ action: 'pause_hint' })]
|
|
)
|
|
const j = JSON.parse(raw)
|
|
t.is(j.schema, 2)
|
|
t.is(j.ok, true)
|
|
t.is(j.normalizedIntent?.action, 'pause_hint')
|
|
t.is(audit.length, 1)
|
|
t.is(audit[0].kind, 'disk_os.replication_operator_intent')
|
|
t.is(audit[0].intent?.action, 'pause_hint')
|
|
} finally {
|
|
if (prev === undefined) delete env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC
|
|
else env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC = prev
|
|
}
|
|
})
|
|
|
|
test('disk.os replication_operator_intent EINVAL for unknown action', async (t) => {
|
|
const bridge = createBareOsDiskOsBridge({
|
|
drive: null,
|
|
bareOsIpc: { list: () => [] },
|
|
ctxApiVersion: BARE_OS_CTX_API_VERSION,
|
|
systemRevision: null,
|
|
bootStartedMs: Date.now()
|
|
})
|
|
const env = hostEnv()
|
|
if (!env) {
|
|
t.pass('host env unavailable in this bare runtime')
|
|
return
|
|
}
|
|
const prev = env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC
|
|
env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC = '1'
|
|
try {
|
|
const raw = await bridge.execRpc(
|
|
'bare_os',
|
|
'replication_operator_intent',
|
|
[JSON.stringify({ action: 'nope' })]
|
|
)
|
|
const j = JSON.parse(raw)
|
|
t.is(j.schema, 2)
|
|
t.is(j.ok, false)
|
|
t.is(j.code, 'EINVAL')
|
|
t.ok(Array.isArray(j.allowedActions))
|
|
} finally {
|
|
if (prev === undefined) delete env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC
|
|
else env.BARE_OS_DISK_OS_OPERATOR_INTENT_RPC = prev
|
|
}
|
|
})
|
|
|
|
test('MBR corruption fixture rejects parse', (t) => {
|
|
const primary = crypto.hash(b4a.from('bare-smoke-primary'))
|
|
const block = buildMbr(primary)
|
|
t.is(block.byteLength, BLOCK_SIZE)
|
|
const corrupted = b4a.from(block)
|
|
// Flip bytes inside header so parseMbr rejects deterministically.
|
|
corrupted[0] ^= 0xff
|
|
corrupted[1] ^= 0xff
|
|
t.exception(() => parseMbr(corrupted))
|
|
})
|
|
|
|
test('wrong-topic fixture differs from bare-os-v1 topic key', (t) => {
|
|
const canonical = topicKey()
|
|
const wrongTopic = crypto.hash(b4a.from(TOPIC_STRING + '-wrong-topic-fixture'))
|
|
t.is(canonical.byteLength, 32)
|
|
t.is(wrongTopic.byteLength, 32)
|
|
t.unlike(canonical, wrongTopic)
|
|
})
|