fix(pi-ssh): harden remote execution and search

This commit is contained in:
云服务部-叶林立
2026-08-24 23:04:29 +08:00
parent a7891f18bf
commit aff91b0972
30 changed files with 1063 additions and 222 deletions
+62 -1
View File
@@ -182,12 +182,15 @@ test("connects with password auth, pins the host key, and streams exec output",
assert.equal(fake.connectConfig?.hostVerifier?.(fixtureKey("wrong")), false);
const output: Buffer[] = [];
const stderr: Buffer[] = [];
const result = await transport.exec("printf ok", "/srv/build", {
onData: (data) => output.push(data),
onStderr: (data) => stderr.push(data),
timeout: 5,
});
assert.equal(result.exitCode, 7);
assert.equal(Buffer.concat(output).toString("utf8"), "stdout\nstderr\n");
assert.equal(Buffer.concat(output).toString("utf8"), "stdout\n");
assert.equal(Buffer.concat(stderr).toString("utf8"), "stderr\n");
assert.match(fake.command ?? "", /^cd -- '\/srv\/build' && bash -lc 'printf ok' <\/dev\/null$/);
await transport.dispose();
assert.equal(fake.ended, true);
@@ -279,6 +282,64 @@ test("falls back to direct overwrite when SFTP v3 rename cannot replace", async
await transport.dispose();
});
test("aborts an in-progress SSH connection attempt", async () => {
const fake = new FakeClient();
fake.connectAction = () => {};
const transport = new Ssh2Transport(passwordHost(), fake as unknown as Client);
const controller = new AbortController();
const connecting = transport.connect(controller.signal);
await new Promise<void>((resolve) => setImmediate(resolve));
controller.abort();
await assert.rejects(connecting, /SSH connection aborted/);
assert.equal(fake.destroyed, true);
await transport.dispose();
});
test("allows four independent exec channels and bounds additional commands", async () => {
const fake = new FakeClient();
const channels: FakeChannel[] = [];
fake.execAction = (_command, callback) => {
const channel = new FakeChannel();
channels.push(channel);
callback(undefined, channel as ClientChannel);
};
const transport = new Ssh2Transport(passwordHost(), fake as unknown as Client);
await transport.connect();
const commands = Array.from({ length: 5 }, (_, index) =>
transport.exec(`command-${index}`, "/srv", { onData() {}, timeout: 0 }),
);
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(channels.length, 4);
channels[0]?.emit("close", 0);
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(channels.length, 5);
for (const channel of channels.slice(1)) channel.emit("close", 0);
await Promise.all(commands);
await transport.dispose();
});
test("cancels an exec while it is waiting for a concurrency slot", async () => {
const fake = new FakeClient();
const channels: FakeChannel[] = [];
fake.execAction = (_command, callback) => {
const channel = new FakeChannel();
channels.push(channel);
callback(undefined, channel as ClientChannel);
};
const transport = new Ssh2Transport(passwordHost(), fake as unknown as Client);
await transport.connect();
const active = Array.from({ length: 4 }, () => transport.exec("sleep", "/srv", { onData() {}, timeout: 0 }));
await new Promise<void>((resolve) => setImmediate(resolve));
const controller = new AbortController();
const queued = transport.exec("queued", "/srv", { onData() {}, timeout: 0, signal: controller.signal });
controller.abort();
await assert.rejects(queued, /SSH command aborted/);
assert.equal(channels.length, 4);
for (const channel of channels) channel.emit("close", 0);
await Promise.all(active);
await transport.dispose();
});
test("aborts and times out commands by closing the active channel", async () => {
const abortClient = new FakeClient();
const abortChannel = new FakeChannel();