summaryrefslogtreecommitdiffhomepage
path: root/packages/ssh/src/integration.test.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-26 22:03:19 +0900
committerAdam Malczewski <[email protected]>2026-06-26 22:23:39 +0900
commit727c98c9dae516a2070eb950410314380a20c974 (patch)
tree52aa1022c54f11770be7e4e2a324f0a8b8b8deec /packages/ssh/src/integration.test.ts
parente59dc11f63b1df51142259bb2c406af8c9c8c2bb (diff)
downloaddispatch-727c98c9dae516a2070eb950410314380a20c974.tar.gz
dispatch-727c98c9dae516a2070eb950410314380a20c974.zip
style: switch from tabs to 2-space indentation
Diffstat (limited to 'packages/ssh/src/integration.test.ts')
-rw-r--r--packages/ssh/src/integration.test.ts272
1 files changed, 136 insertions, 136 deletions
diff --git a/packages/ssh/src/integration.test.ts b/packages/ssh/src/integration.test.ts
index 7b05be2..bfbecd8 100644
--- a/packages/ssh/src/integration.test.ts
+++ b/packages/ssh/src/integration.test.ts
@@ -29,8 +29,8 @@ const testEnv = HOST === undefined ? null : { host: HOST, port: PORT, user: USER
// Build a real config env fixture pointing at the test sshd.
function configText(): string {
- if (testEnv === null) return "";
- return `Host testremote\n HostName ${testEnv.host}\n Port ${testEnv.port}\n User ${testEnv.user}\n`;
+ if (testEnv === null) return "";
+ return `Host testremote\n HostName ${testEnv.host}\n Port ${testEnv.port}\n User ${testEnv.user}\n`;
}
const sshDir = join(homedir(), ".ssh");
@@ -41,144 +41,144 @@ const sshDir = join(homedir(), ".ssh");
* returns itself so the type is complete (the integration test logs nothing).
*/
function noopLogger(): Logger {
- const log: Logger = {
- debug: () => undefined,
- info: () => undefined,
- warn: () => undefined,
- error: () => undefined,
- child: () => log,
- span: (name: string) => ({
- id: name,
- log,
- setAttributes: () => undefined,
- addLink: () => undefined,
- child: (n: string) =>
- ({
- id: n,
- log,
- setAttributes: () => undefined,
- addLink: () => undefined,
- child: () => ({ id: n, log }) as never,
- end: () => undefined,
- }) as never,
- end: () => undefined,
- }),
- };
- return log;
+ const log: Logger = {
+ debug: () => undefined,
+ info: () => undefined,
+ warn: () => undefined,
+ error: () => undefined,
+ child: () => log,
+ span: (name: string) => ({
+ id: name,
+ log,
+ setAttributes: () => undefined,
+ addLink: () => undefined,
+ child: (n: string) =>
+ ({
+ id: n,
+ log,
+ setAttributes: () => undefined,
+ addLink: () => undefined,
+ child: () => ({ id: n, log }) as never,
+ end: () => undefined,
+ }) as never,
+ end: () => undefined,
+ }),
+ };
+ return log;
}
function realDeps() {
- return {
- logger: noopLogger(),
- homeDir: homedir(),
- knownHostsPath: join(sshDir, "known_hosts"),
- readFileText: (p: string) => readFile(p, "utf8"),
- appendKnownHosts: async () => undefined, // don't mutate the real known_hosts in a test
- pathExists: (p: string) =>
- access(p)
- .then(() => true)
- .catch(() => false),
- newClient: () => new Client(),
- resolveComputer: async (alias: string) =>
- resolveComputer(alias, {
- configText: configText(),
- knownHostsText: "",
- defaultUser: USER,
- homeDir: homedir(),
- }),
- };
+ return {
+ logger: noopLogger(),
+ homeDir: homedir(),
+ knownHostsPath: join(sshDir, "known_hosts"),
+ readFileText: (p: string) => readFile(p, "utf8"),
+ appendKnownHosts: async () => undefined, // don't mutate the real known_hosts in a test
+ pathExists: (p: string) =>
+ access(p)
+ .then(() => true)
+ .catch(() => false),
+ newClient: () => new Client(),
+ resolveComputer: async (alias: string) =>
+ resolveComputer(alias, {
+ configText: configText(),
+ knownHostsText: "",
+ defaultUser: USER,
+ homeDir: homedir(),
+ }),
+ };
}
describe.skipIf(testEnv === null)("SshExecBackend against a real sshd", () => {
- let pool: ReturnType<typeof createSshConnectionPool>;
- let tmpRemoteDir: string;
-
- beforeEach(async () => {
- pool = createSshConnectionPool(realDeps());
- // Create a remote temp dir to run cwd-scoped commands in.
- tmpRemoteDir = await mkdtemp(join(tmpdir(), "ssh-int-"));
- });
-
- afterEach(async () => {
- await pool.closeAll();
- // best-effort cleanup of the remote temp dir.
- const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
- try {
- await backend.spawn({
- command: `rm -rf ${tmpRemoteDir}`,
- cwd: "/",
- signal: new AbortController().signal,
- timeout: 5000,
- onOutput: () => undefined,
- });
- } catch {
- // ignore
- }
- });
-
- it("connects + execs a command, returning stdout + exit code", async () => {
- const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
- let stdout = "";
- const res = await backend.spawn({
- command: "echo integration_ok; exit 7",
- cwd: tmpRemoteDir,
- signal: new AbortController().signal,
- timeout: 10000,
- onOutput: (data, stream) => {
- if (stream === "stdout") stdout += data;
- },
- });
- expect(stdout.trim()).toBe("integration_ok");
- expect(res.exitCode).toBe(7);
- expect(res.timedOut).toBe(false);
- expect(res.aborted).toBe(false);
- });
-
- it("writes a file over SFTP then reads it back", async () => {
- const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
- const path = join(tmpRemoteDir, "sftp-probe.txt");
- await backend.writeFile(path, "hello-sftp");
- const content = await backend.readFile(path);
- expect(content).toBe("hello-sftp");
- });
-
- it("stat reports isFile/isDirectory correctly", async () => {
- const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
- const path = join(tmpRemoteDir, "stat-probe.txt").replace(/\\/g, "/");
- await backend.writeFile(path, "x");
- const s = await backend.stat(path);
- expect(s.isFile).toBe(true);
- expect(s.isDirectory).toBe(false);
- // A directory stat reports the inverse.
- const dirStat = await backend.stat(tmpRemoteDir);
- expect(dirStat.isDirectory).toBe(true);
- expect(dirStat.isFile).toBe(false);
- });
-
- it("readdir lists entries with isDirectory flags", async () => {
- const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
- await backend.writeFile(join(tmpRemoteDir, "a.txt").replace(/\\/g, "/"), "a");
- await mkdir(join(tmpRemoteDir, "subdir").replace(/\\/g, "/")).catch(() => undefined);
- const entries = await backend.readdir(tmpRemoteDir);
- const names = entries.map((e) => e.name);
- expect(names).toContain("a.txt");
- expect(entries.find((e) => e.name === "a.txt")?.isDirectory).toBe(false);
- });
-
- it("readFile on a missing path throws an ENOENT .code error", async () => {
- const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
- await expect(
- backend.readFile(join(tmpRemoteDir, "nope.txt").replace(/\\/g, "/")),
- ).rejects.toMatchObject({
- code: "ENOENT",
- });
- });
-
- it("exists returns false for a missing path and true for an existing one", async () => {
- const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
- const path = join(tmpRemoteDir, "exists-probe.txt").replace(/\\/g, "/");
- await backend.writeFile(path, "x");
- expect(await backend.exists(path)).toBe(true);
- expect(await backend.exists(join(tmpRemoteDir, "missing.txt").replace(/\\/g, "/"))).toBe(false);
- });
+ let pool: ReturnType<typeof createSshConnectionPool>;
+ let tmpRemoteDir: string;
+
+ beforeEach(async () => {
+ pool = createSshConnectionPool(realDeps());
+ // Create a remote temp dir to run cwd-scoped commands in.
+ tmpRemoteDir = await mkdtemp(join(tmpdir(), "ssh-int-"));
+ });
+
+ afterEach(async () => {
+ await pool.closeAll();
+ // best-effort cleanup of the remote temp dir.
+ const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
+ try {
+ await backend.spawn({
+ command: `rm -rf ${tmpRemoteDir}`,
+ cwd: "/",
+ signal: new AbortController().signal,
+ timeout: 5000,
+ onOutput: () => undefined,
+ });
+ } catch {
+ // ignore
+ }
+ });
+
+ it("connects + execs a command, returning stdout + exit code", async () => {
+ const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
+ let stdout = "";
+ const res = await backend.spawn({
+ command: "echo integration_ok; exit 7",
+ cwd: tmpRemoteDir,
+ signal: new AbortController().signal,
+ timeout: 10000,
+ onOutput: (data, stream) => {
+ if (stream === "stdout") stdout += data;
+ },
+ });
+ expect(stdout.trim()).toBe("integration_ok");
+ expect(res.exitCode).toBe(7);
+ expect(res.timedOut).toBe(false);
+ expect(res.aborted).toBe(false);
+ });
+
+ it("writes a file over SFTP then reads it back", async () => {
+ const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
+ const path = join(tmpRemoteDir, "sftp-probe.txt");
+ await backend.writeFile(path, "hello-sftp");
+ const content = await backend.readFile(path);
+ expect(content).toBe("hello-sftp");
+ });
+
+ it("stat reports isFile/isDirectory correctly", async () => {
+ const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
+ const path = join(tmpRemoteDir, "stat-probe.txt").replace(/\\/g, "/");
+ await backend.writeFile(path, "x");
+ const s = await backend.stat(path);
+ expect(s.isFile).toBe(true);
+ expect(s.isDirectory).toBe(false);
+ // A directory stat reports the inverse.
+ const dirStat = await backend.stat(tmpRemoteDir);
+ expect(dirStat.isDirectory).toBe(true);
+ expect(dirStat.isFile).toBe(false);
+ });
+
+ it("readdir lists entries with isDirectory flags", async () => {
+ const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
+ await backend.writeFile(join(tmpRemoteDir, "a.txt").replace(/\\/g, "/"), "a");
+ await mkdir(join(tmpRemoteDir, "subdir").replace(/\\/g, "/")).catch(() => undefined);
+ const entries = await backend.readdir(tmpRemoteDir);
+ const names = entries.map((e) => e.name);
+ expect(names).toContain("a.txt");
+ expect(entries.find((e) => e.name === "a.txt")?.isDirectory).toBe(false);
+ });
+
+ it("readFile on a missing path throws an ENOENT .code error", async () => {
+ const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
+ await expect(
+ backend.readFile(join(tmpRemoteDir, "nope.txt").replace(/\\/g, "/")),
+ ).rejects.toMatchObject({
+ code: "ENOENT",
+ });
+ });
+
+ it("exists returns false for a missing path and true for an existing one", async () => {
+ const backend = createSshExecBackend("testremote", async (a) => pool.acquire(a));
+ const path = join(tmpRemoteDir, "exists-probe.txt").replace(/\\/g, "/");
+ await backend.writeFile(path, "x");
+ expect(await backend.exists(path)).toBe(true);
+ expect(await backend.exists(join(tmpRemoteDir, "missing.txt").replace(/\\/g, "/"))).toBe(false);
+ });
});