mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 00:27:39 +00:00
test(runtime): make the SSH guard test observe the corruption it names
The test asserted `gitSpawn` was never called and no repo was registered, but neither assertion could fail. `/home/brennan` is unwritable on macOS, so the pre-guard clone died at `mkdir` before reaching `gitSpawn`, and `/home/brennan/orca` failed `isGitRepo` before reaching `addRepo` — the exact side effects under test were unreachable either way. `rejects.toThrow` also aborted the test before those lines ran. Use a real temp destination and a real temp git repo, await both calls via `.catch`, and assert the side effects before the wording. With the guard disabled the test now fails on `gitSpawn` being called once with a real `git clone`, and on a repo registered stamped `executionHostId: 'ssh:openclaw'` — the silent local-clone-recorded-as-remote defect itself. `gitSpawn` is stubbed so a regression records the call instead of hitting the network. Also document the SSH restriction on `project setup-existing-folder`, which the guard now rejects. `setup-clone` already carried that note; its sibling did not.
This commit is contained in:
@@ -27,7 +27,10 @@ export const PROJECT_COMMAND_SPECS: CommandSpec[] = [
|
||||
usage:
|
||||
'orca project setup-existing-folder --project <id> --host <host-id> --path <path> [--kind git|folder] [--display-name <name>] [--json]',
|
||||
allowedFlags: [...GLOBAL_FLAGS, 'project', 'host', 'path', 'kind', 'display-name'],
|
||||
notes: ['For remote runtimes, --path must be an absolute path on the remote server.'],
|
||||
notes: [
|
||||
'For remote runtimes, --path must be an absolute path on the remote server.',
|
||||
'SSH targets are set up through the desktop UI because the desktop client owns SSH connections.'
|
||||
],
|
||||
examples: [
|
||||
'orca project setup-existing-folder --project github:stablyai/orca --host local --path ~/orca',
|
||||
'orca project setup-existing-folder --project github:stablyai/orca --host runtime:gpu --path /home/me/orca --kind git --json'
|
||||
|
||||
@@ -7160,7 +7160,21 @@ describe('OrcaRuntimeService', () => {
|
||||
})
|
||||
|
||||
it('refuses SSH hosts instead of setting the project up on the local machine', async () => {
|
||||
const spawnSpy = vi.spyOn(gitRunner, 'gitSpawn')
|
||||
// Why: both inputs must be paths the pre-guard code would have accepted. An unwritable
|
||||
// destination fails at mkdir and a non-repo path fails at isGitRepo, which would leave the
|
||||
// side-effect assertions below unable to observe the local clone/probe they exist to catch.
|
||||
const destination = await mkdtemp(join(tmpdir(), 'orca-runtime-ssh-guard-'))
|
||||
const existingFolder = join(destination, 'orca')
|
||||
mkdirSync(existingFolder, { recursive: true })
|
||||
execFileSync('git', ['init'], { cwd: existingFolder, stdio: 'ignore' })
|
||||
const spawnSpy = vi.spyOn(gitRunner, 'gitSpawn').mockImplementation(() => {
|
||||
// Why: unreachable while the guard holds; stubbed so a regression records the call
|
||||
// instead of shelling out to a real network clone.
|
||||
const proc = new EventEmitter() as EventEmitter & { stderr: EventEmitter }
|
||||
proc.stderr = new EventEmitter()
|
||||
queueMicrotask(() => proc.emit('close', 1, null))
|
||||
return proc as never
|
||||
})
|
||||
const repos: Record<string, unknown>[] = []
|
||||
const runtimeStore = {
|
||||
...store,
|
||||
@@ -7172,29 +7186,37 @@ describe('OrcaRuntimeService', () => {
|
||||
const runtime = new OrcaRuntimeService(runtimeStore as never)
|
||||
|
||||
try {
|
||||
await expect(
|
||||
runtime.setupProjectClone({
|
||||
const cloneError = await runtime
|
||||
.setupProjectClone({
|
||||
projectId: 'github:stablyai/orca',
|
||||
hostId: 'ssh:openclaw',
|
||||
url: 'https://example.com/orca.git',
|
||||
destination: '/home/brennan'
|
||||
destination
|
||||
})
|
||||
).rejects.toThrow(/SSH hosts are not supported/)
|
||||
|
||||
await expect(
|
||||
runtime.setupProjectExistingFolder({
|
||||
.catch((error: unknown) => error)
|
||||
const existingFolderError = await runtime
|
||||
.setupProjectExistingFolder({
|
||||
projectId: 'github:stablyai/orca',
|
||||
hostId: 'ssh:openclaw',
|
||||
path: '/home/brennan/orca',
|
||||
path: existingFolder,
|
||||
kind: 'git'
|
||||
})
|
||||
).rejects.toThrow(/SSH hosts are not supported/)
|
||||
.catch((error: unknown) => error)
|
||||
|
||||
// Why: the defect was a silent local clone/probe recorded as remote, not a bad message.
|
||||
// Why: the defect was a silent local clone/probe recorded as remote, not a bad message,
|
||||
// so the absent side effects are asserted before the wording. Both calls are awaited
|
||||
// first so a regression reports the corruption rather than stopping at the first throw.
|
||||
expect(spawnSpy).not.toHaveBeenCalled()
|
||||
expect(repos).toHaveLength(0)
|
||||
expect(cloneError).toMatchObject({
|
||||
message: expect.stringMatching(/SSH hosts are not supported/)
|
||||
})
|
||||
expect(existingFolderError).toMatchObject({
|
||||
message: expect.stringMatching(/SSH hosts are not supported/)
|
||||
})
|
||||
} finally {
|
||||
spawnSpy.mockRestore()
|
||||
await rm(destination, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user