Files
orca/src/main/ssh/ssh-system-transport.integration.test.ts
T
OrcaWinandm4air 5f308bfa9c revert: take the 26 Phase 3 (#16741 port) PRs back out of main (#24559)
* Revert "feat(orcad): source-side dormant export of a relay-hosted SSH target (#16741 T6-8) (#24519)"

This reverts commit 783101b304.

* Revert "feat(ssh): update, roll back, recover and stop a managed orcad server (#16741 T6-5 follow-up) (#24463)"

This reverts commit 38c2d1dcb9.

* Revert "feat(ssh): deploy and pair an empty managed orcad server over SSH (#16741 T6-5) (#24453)"

This reverts commit 8b76683b40.

* Revert "fix(ssh): orcad GC honors the activation journal; readiness requires proven daemon coverage (#16741 T6 follow-up) (#24451)"

This reverts commit d3f8c5063b.

* Revert "feat(ssh): remote orcad stop by request file and journaled decommission (#16741 T6-4) (#24449)"

This reverts commit 43d9b43d3f.

* Revert "feat(orcad): supervisable server: stop requests, managed stop receipts and a lifetime that keeps its lock on failed teardown (#16741 T6-3) (#24433)"

This reverts commit b093d3ab20.

* Revert "feat(ssh): crash-safe orcad activation, rollback and recovery (#16741 T6-2) (#24423)"

This reverts commit 1a9ac0e955.

* Revert "feat(runtime): SSH access links for paired servers in a downgrade-safe sidecar (#16741 T5-1+T5-2) (#24420)"

This reverts commit 99db2bfae4.

* Revert "feat(relay): capability-gated owner reset with a durable preparation journal (#16741 T3 R1) (#24418)"

This reverts commit 34a582bd39.

* Revert "feat(ssh): track connection-manager drains, test probes and provider continuations (#16741 T2 P3+P8a) (#24407)"

This reverts commit d53063d2b1.

* Revert "feat(daemon): idle retirement, session census and recovery-only provider (#16741 T2 P4b) (#24409)"

This reverts commit ff212dbbef.

* Revert "feat(ssh): add pty.resumeClient and split SSH PTY process listing (#16741 T2 P5+P6) (#24414)"

This reverts commit 92cb71765e.

* Revert "feat(relay): await owned watcher and agent children on shutdown (#16741 T2 P1) (#24400)"

This reverts commit 6b36e4f85b.

* Revert "feat(session): retry failed renderer session writes and verify local folder PTYs (#16741 T2 P9) (#24406)"

This reverts commit d23ecef301.

* Revert "feat(ssh): remote orcad primitives on the pinned Node runtime (#16741 T6-1) (#24419)"

This reverts commit dd87ae578d.

* Revert "fix(runtime): fence runtime-environment subscriptions and status probes by identity (#16741 T5-3) (#24421)"

This reverts commit ece9e4d2e3.

* Revert "feat(orcad): migration manifest and dormant-state contracts (#16741 T6-7) (#24422)"

This reverts commit 3fbdaba262.

* Revert "feat(ssh): wire SshConnection through the work and transport close ledgers (#16741 T2 P2) (#24401)"

This reverts commit 4e8edc8872.

* Revert "feat(profiles): carry markdown frontmatter visibility in project transfers (#16741 T2 P7) (#24405)"

This reverts commit 60c93263cc.

* Revert "fix(runtime): project the PTY incarnation onto mobile session tabs (#24413)"

This reverts commit 99e0303572.

* Revert "feat(daemon): tag daemon stream data with the PTY incarnation id (#16741 T2 P4a) (#24402)"

This reverts commit 817af768b0.

* Revert "feat(ssh): port the SSH connection work ledger and transport close ledger (#16741 T2) (#24210)"

This reverts commit c9918931c8.

* Revert "feat(relay): fence and drain file and git response streams on shutdown (#24185)"

This reverts commit dc08ffeba9.

* Revert "refactor(runtime-rpc): extract the Node WebSocket lifecycle; opt-in pinned port (#24186)"

This reverts commit a789233bbb.

* Revert "feat(relay): route relay handlers through work admission; producer publication drain (#24181)"

This reverts commit 0b812bd698.

* Revert "feat(relay): land the #16741 T1 seam (work drain, publication drain, release gate) (#24156)"

This reverts commit 3aa2d3af7c.

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-02 00:52:32 -07:00

270 lines
8.3 KiB
TypeScript

import { mkdtempSync, writeFileSync, mkdirSync, chmodSync, rmSync, readFileSync } from 'node:fs'
import { join } from 'node:path'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
vi.mock('electron', () => ({
app: { getAppPath: () => '/mock/app' }
}))
import { SshConnection } from './ssh-connection'
import { deployAndLaunchRelay } from './ssh-relay-deploy'
import { SshChannelMultiplexer } from './ssh-channel-multiplexer'
import { uploadDirectoryViaSystemSsh } from './ssh-system-fallback'
import type { SshTarget } from '../../shared/ssh-types'
import { relayArtifactFilenames } from '../../shared/relay-artifacts'
const RELAY_VERSION = '0.1.0+systemtransport'
function makeTarget(): SshTarget {
return {
id: 'system-transport-target',
label: 'System Transport Target',
configHost: 'fdpass-host',
host: 'ignored.example.com',
port: 22,
username: ''
}
}
function writeFakeSsh(dir: string): string {
const path = join(dir, 'fake-ssh')
writeFileSync(
path,
`#!/bin/sh
while [ "$#" -gt 0 ]; do
case "$1" in
-o|-p|-i|-J|-S) shift 2 ;;
-T) shift ;;
--) shift; break ;;
-*) shift ;;
*) break ;;
esac
done
if [ "$#" -gt 0 ]; then
shift
fi
cmd="$1"
if [ -z "$cmd" ]; then
exit 0
fi
exec /bin/sh -c "$cmd"
`
)
chmodSync(path, 0o755)
return path
}
function writeFakeRelay(dir: string): void {
// Stage every companion the manifest declares — relay.js gets real content
// below — so adding one cannot silently fail the completeness probe here.
for (const filename of relayArtifactFilenames(false)) {
if (filename !== 'relay.js') {
writeFileSync(join(dir, filename), '')
}
}
writeFileSync(
join(dir, 'relay.js'),
`
const fs = require('fs');
const net = require('net');
const sentinel = 'ORCA-RELAY v0.1.0 READY\\n';
const sockPath = process.argv[process.argv.indexOf('--sock-path') + 1];
function encode(msg) {
const payload = Buffer.from(JSON.stringify(msg), 'utf8');
const header = Buffer.alloc(13);
header[0] = 1;
header.writeUInt32BE(1, 1);
header.writeUInt32BE(0, 5);
header.writeUInt32BE(payload.length, 9);
return Buffer.concat([header, payload]);
}
function serve(socket, onResolved) {
socket.on('error', () => {});
socket.write(sentinel);
let buffer = Buffer.alloc(0);
socket.on('data', (chunk) => {
buffer = Buffer.concat([buffer, chunk]);
while (buffer.length >= 13) {
const type = buffer[0];
const length = buffer.readUInt32BE(9);
if (buffer.length < 13 + length) return;
const payload = buffer.subarray(13, 13 + length);
buffer = buffer.subarray(13 + length);
if (type !== 1) continue;
const message = JSON.parse(payload.toString('utf8'));
if (message.method === 'session.resolveHome') {
socket.write(
encode({ jsonrpc: '2.0', id: message.id, result: process.env.HOME }),
onResolved
);
}
}
});
}
if (process.argv.includes('--detached')) {
try { fs.unlinkSync(sockPath); } catch {}
const server = net.createServer((socket) => {
serve(socket, () => server.close());
});
server.listen(sockPath);
} else if (process.argv.includes('--connect')) {
const socket = net.createConnection(sockPath);
socket.on('error', (error) => {
process.stderr.write(error.message);
process.exit(1);
});
process.stdin.pipe(socket);
socket.pipe(process.stdout);
}
`
)
}
function createRelayTree(root: string, remoteHome: string): void {
const platforms = [
'linux-x64',
'linux-arm64',
'darwin-x64',
'darwin-arm64',
'win32-x64',
'win32-arm64'
]
for (const platform of platforms) {
const localDir = join(root, platform)
mkdirSync(localDir, { recursive: true })
writeFileSync(join(localDir, '.version'), RELAY_VERSION)
writeFakeRelay(localDir)
}
const remoteDir = join(remoteHome, '.orca-remote', `relay-${RELAY_VERSION}`)
mkdirSync(join(remoteDir, 'node_modules', 'node-pty', 'lib'), { recursive: true })
mkdirSync(join(remoteDir, 'node_modules', '@parcel', 'watcher'), { recursive: true })
writeFileSync(join(remoteDir, 'node_modules', 'node-pty', 'index.js'), '')
writeFileSync(
join(remoteDir, 'node_modules', 'node-pty', 'lib', 'utils.js'),
'exports.loadNativeModule = () => ({})\n'
)
writeFileSync(join(remoteDir, 'node_modules', '@parcel', 'watcher', 'index.js'), '')
writeFileSync(join(remoteDir, '.install-complete'), '')
writeFakeRelay(remoteDir)
}
describe('system SSH transport integration', () => {
let tempDir: string
let oldHome: string | undefined
let oldRelayPath: string | undefined
let oldSystemSshPath: string | undefined
let oldForceSystemTransport: string | undefined
beforeEach(() => {
if (process.platform === 'win32') {
return
}
tempDir = mkdtempSync(join('/tmp', 'orca-ssh-'))
oldHome = process.env.HOME
oldRelayPath = process.env.ORCA_RELAY_PATH
oldSystemSshPath = process.env.ORCA_SYSTEM_SSH_PATH
oldForceSystemTransport = process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT
const remoteHome = join(tempDir, 'remote-home')
const relayRoot = join(tempDir, 'relay')
mkdirSync(remoteHome, { recursive: true })
createRelayTree(relayRoot, remoteHome)
process.env.HOME = remoteHome
process.env.ORCA_RELAY_PATH = relayRoot
process.env.ORCA_SYSTEM_SSH_PATH = writeFakeSsh(tempDir)
process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT = '1'
})
afterEach(() => {
if (process.platform === 'win32') {
return
}
if (oldHome === undefined) {
delete process.env.HOME
} else {
process.env.HOME = oldHome
}
if (oldRelayPath === undefined) {
delete process.env.ORCA_RELAY_PATH
} else {
process.env.ORCA_RELAY_PATH = oldRelayPath
}
if (oldSystemSshPath === undefined) {
delete process.env.ORCA_SYSTEM_SSH_PATH
} else {
process.env.ORCA_SYSTEM_SSH_PATH = oldSystemSshPath
}
if (oldForceSystemTransport === undefined) {
delete process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT
} else {
process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT = oldForceSystemTransport
}
rmSync(tempDir, { recursive: true, force: true })
})
// Why: this fixture writes a POSIX fake ssh script to exercise stdin/stdout
// transport semantics; Windows coverage stays in argument/unit tests.
it.skipIf(process.platform === 'win32')(
'deploys and speaks relay RPC over a system ssh process for ProxyUseFdpass targets',
async () => {
const conn = new SshConnection(makeTarget(), { onStateChange: vi.fn() })
const onProgress = vi.fn()
await conn.connect()
expect(conn.usesSystemSshTransport()).toBe(true)
const result = await deployAndLaunchRelay(conn, onProgress, 60, makeTarget().id)
expect(onProgress).toHaveBeenCalledWith('Starting relay...')
expect(onProgress).not.toHaveBeenCalledWith('Uploading relay...')
expect(onProgress).not.toHaveBeenCalledWith('Installing native dependencies...')
const mux = new SshChannelMultiplexer(result.transport)
try {
await expect(mux.request('session.resolveHome', { path: '~' })).resolves.toBe(
join(tempDir, 'remote-home')
)
} finally {
mux.dispose()
await conn.disconnect()
}
},
20_000
)
it.skipIf(process.platform === 'win32')(
'connects GSSAPI-flagged targets through system ssh without the force override',
async () => {
delete process.env.ORCA_SSH_FORCE_SYSTEM_TRANSPORT
const conn = new SshConnection(
{ ...makeTarget(), source: 'manual', gssapiAuthentication: true },
{ onStateChange: vi.fn() }
)
await conn.connect()
try {
expect(conn.usesSystemSshTransport()).toBe(true)
expect(conn.getState().status).toBe('connected')
} finally {
await conn.disconnect()
}
},
20_000
)
it.skipIf(process.platform === 'win32')(
'uploads a directory through the system ssh stdin/stdout path',
async () => {
const source = join(tempDir, 'source')
const destination = join(tempDir, 'uploaded')
mkdirSync(source, { recursive: true })
writeFileSync(join(source, 'payload.txt'), 'uploaded over system ssh')
await uploadDirectoryViaSystemSsh(makeTarget(), source, destination)
expect(readFileSync(join(destination, 'payload.txt'), 'utf8')).toBe(
'uploaded over system ssh'
)
}
)
})