[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
This commit is contained in:
91
electron/bridges/sshIdleParkPolicy.test.cjs
Normal file
91
electron/bridges/sshIdleParkPolicy.test.cjs
Normal file
@@ -0,0 +1,91 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { EventEmitter } = require("node:events");
|
||||
|
||||
const {
|
||||
DEFAULT_REUSED_SHELL_LIVENESS_MS,
|
||||
remoteAllowsIdleParkedShellReuse,
|
||||
remoteNeedsReusedShellLivenessCheck,
|
||||
shouldConfirmReusedShellLiveness,
|
||||
resolveReusedShellLivenessMs,
|
||||
waitForReusedShellLiveness,
|
||||
} = require("./sshIdleParkPolicy.cjs");
|
||||
|
||||
test("TERM-SSHD cannot host a later shell on a parked transport", () => {
|
||||
assert.equal(remoteAllowsIdleParkedShellReuse("TERM-SSHD"), false);
|
||||
assert.equal(remoteAllowsIdleParkedShellReuse("SSH-2.0-TERM-SSHD"), false);
|
||||
assert.equal(remoteAllowsIdleParkedShellReuse("term-sshd"), false);
|
||||
});
|
||||
|
||||
test("OpenSSH and Dropbear still allow idle-park shell reuse", () => {
|
||||
assert.equal(remoteAllowsIdleParkedShellReuse("OpenSSH_9.6"), true);
|
||||
assert.equal(remoteAllowsIdleParkedShellReuse("SSH-2.0-OpenSSH_9.6"), true);
|
||||
assert.equal(remoteAllowsIdleParkedShellReuse("dropbear_2024.85"), true);
|
||||
assert.equal(remoteAllowsIdleParkedShellReuse(""), true);
|
||||
});
|
||||
|
||||
test("shouldConfirmReusedShellLiveness covers idle park and SFTP-held last-shell close", () => {
|
||||
assert.equal(shouldConfirmReusedShellLiveness({
|
||||
state: "idle",
|
||||
remoteSshVersion: "CustomBastion_1.0",
|
||||
}), true);
|
||||
assert.equal(shouldConfirmReusedShellLiveness({
|
||||
state: "live",
|
||||
pendingShellReconnectRisk: { oldShellPids: [], hasUnknownOldShell: true },
|
||||
remoteSshVersion: "TERM-SSHD",
|
||||
}), true);
|
||||
assert.equal(shouldConfirmReusedShellLiveness({
|
||||
state: "live",
|
||||
remoteSshVersion: "CustomBastion_1.0",
|
||||
}), false);
|
||||
assert.equal(shouldConfirmReusedShellLiveness({
|
||||
state: "idle",
|
||||
remoteSshVersion: "OpenSSH_9.0",
|
||||
}), false);
|
||||
});
|
||||
|
||||
test("unknown banners get a reused-shell liveness check; OpenSSH does not", () => {
|
||||
assert.equal(remoteNeedsReusedShellLivenessCheck("TERM-SSHD"), true);
|
||||
assert.equal(remoteNeedsReusedShellLivenessCheck("CustomBastion_1.0"), true);
|
||||
assert.equal(remoteNeedsReusedShellLivenessCheck(""), true);
|
||||
assert.equal(remoteNeedsReusedShellLivenessCheck("OpenSSH_9.0"), false);
|
||||
assert.equal(remoteNeedsReusedShellLivenessCheck("SSH-2.0-OpenSSH_9.0"), false);
|
||||
assert.equal(remoteNeedsReusedShellLivenessCheck("dropbear_2022.83"), false);
|
||||
});
|
||||
|
||||
test("resolveReusedShellLivenessMs clamps invalid values to the default", () => {
|
||||
assert.equal(resolveReusedShellLivenessMs(undefined), DEFAULT_REUSED_SHELL_LIVENESS_MS);
|
||||
assert.equal(resolveReusedShellLivenessMs(-1), DEFAULT_REUSED_SHELL_LIVENESS_MS);
|
||||
assert.equal(resolveReusedShellLivenessMs("nope"), DEFAULT_REUSED_SHELL_LIVENESS_MS);
|
||||
assert.equal(resolveReusedShellLivenessMs(40), 40);
|
||||
assert.equal(resolveReusedShellLivenessMs(0), 0);
|
||||
});
|
||||
|
||||
test("waitForReusedShellLiveness fails when the channel exits before settle", async () => {
|
||||
const stream = new EventEmitter();
|
||||
const pending = waitForReusedShellLiveness(stream, { settleMs: 50 });
|
||||
stream.emit("exit", 0);
|
||||
stream.emit("close");
|
||||
const result = await pending;
|
||||
assert.equal(result.alive, false);
|
||||
assert.equal(result.reason, "exit");
|
||||
assert.equal(result.code, 0);
|
||||
});
|
||||
|
||||
test("waitForReusedShellLiveness keeps buffered output when the shell stays up", async () => {
|
||||
const stream = new EventEmitter();
|
||||
const pending = waitForReusedShellLiveness(stream, { settleMs: 15 });
|
||||
stream.emit("data", Buffer.from("banner\n"));
|
||||
const result = await pending;
|
||||
assert.equal(result.alive, true);
|
||||
assert.equal(result.reason, "settle");
|
||||
assert.equal(Buffer.concat(result.buffered).toString(), "banner\n");
|
||||
});
|
||||
|
||||
test("waitForReusedShellLiveness treats an already-closed stream as dead", async () => {
|
||||
const stream = new EventEmitter();
|
||||
stream.closed = true;
|
||||
const result = await waitForReusedShellLiveness(stream, { settleMs: 50 });
|
||||
assert.equal(result.alive, false);
|
||||
assert.equal(result.reason, "already-closed");
|
||||
});
|
||||
Reference in New Issue
Block a user