Files
lms-fe/tests/camera-bridge-deployment.cjs
T

56 lines
3.1 KiB
JavaScript

const {test} = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs/promises')
const path = require('node:path')
const os = require('node:os')
const vm = require('node:vm')
const ts = require('typescript')
const {createHash} = require('node:crypto')
const {spawnSync} = require('node:child_process')
test('remote visualization stages the bundled bridge over stdin and mounts that revision read-only', async () => {
const source = ts.createSourceFile('index.ts', await fs.readFile(path.join(__dirname, '../src/main/index.ts'), 'utf8'), ts.ScriptTarget.Latest, true)
const fn = source.statements.find(node => ts.isFunctionDeclaration(node) && node.name?.text === 'startRemoteVisualizationBridge')
assert.ok(fn)
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'lms-camera-bridge-'))
const resource = path.resolve(__dirname, '../resources/slam-ros-bridge')
const quote = value => "'" + value.replaceAll("'", "'\\''") + "'"
let launch, transfers = 0
const context = {
normalizeVisualizationStack: () => 'slam3d', normalizeRemoteTarget: target => target,
prepareRemoteRosNetworkConfig: async () => null, visualizationBridgeContainerName: () => 'slam-ros-bridge',
resolveVisualizationBridgeImage: () => 'fixture:arm64', bridgeArtifact: () => null,
slamRosBridgeImage: 'slam:local',
bridgeContainerCommand: () => 'python3 /app/bridge.py', resolveResourceContextPath: () => resource,
readFile: fs.readFile, join: path.join, createHash, quoteShellSingle: quote,
expandRemotePathVar: () => [], reportVisualizationProgress() {},
runUnqueuedSshOutput: async (_target, command, timeout, input) => {
transfers++
assert.equal(timeout, 30000)
assert.ok(input.length > 1000)
const {spawn} = require('node:child_process')
await new Promise((resolve, reject) => {
const child = spawn('bash', ['-c', command], {env: {...process.env, HOME: dir}, stdio:['pipe','ignore','pipe']})
let error = ''
child.stderr.on('data', data => {error += data})
child.on('error', reject)
child.on('close', code => code === 0 ? resolve() : reject(Error(error)))
child.stdin.end(input)
})
return ''
},
runSsh: async (_target, command) => { launch = command }
}
vm.runInNewContext(ts.transpileModule(fn.getText(source), {compilerOptions:{target:ts.ScriptTarget.ES2022}}).outputText, context)
try {
await context.startRemoteVisualizationBridge({workspaceRoot:'/workspace'}, 'slam3d', '77')
assert.equal(transfers, 1)
assert.match(launch, /-v "\$HOME\/\.autonomy-studio\/runtime\/bridges\/[a-f0-9]{64}:\/app:ro"/)
const roots = await fs.readdir(path.join(dir, '.autonomy-studio/runtime/bridges'))
for (const name of ['bridge.py','requirements.txt']) assert.equal(await fs.readFile(path.join(dir,'.autonomy-studio/runtime/bridges',roots[0],name),'utf8'), await fs.readFile(path.join(resource,name),'utf8'))
const syntax = spawnSync('bash', ['-n'], {input:launch,encoding:'utf8'})
assert.equal(syntax.status, 0, syntax.stderr)
assert.ok(launch.includes('docker run'))
} finally {await fs.rm(dir,{recursive:true,force:true})}
})