mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 11:42:52 +00:00
* fix(daemon): keep lifecycle operations on the selected instance Restart reconstructed launch inputs and address fallback could redirect a home-selected shutdown to another daemon. Let supervisors publish bound endpoints, retain their worker restart contract, and share captured local lifecycle ownership between CLI and Desktop. * test(daemon): verify bounded desktop readiness and cancellable artifacts * test(cli): verify reload target hints and durable offline pairing * test(daemon): align lifecycle fixtures with ownership and targeting * fix(daemon): preserve reachability when status details time out Provider discovery can outlast a status request after authentication succeeds. Keep local connection facts separate from unavailable details, while explicit remote queries retain their error outcome. Migrate CLI and packaged Desktop fixtures to persistent managed configuration and explicit targets. Isolate generic Git observation from forge discovery and reuse disposable CLI homes on Windows. * test(daemon): observe restart through the worker status RPC The bounded CLI status observation may omit worker details while an authenticated connection remains healthy. Exercise the app-style restart through its full RPC and retain the replacement observation, with a real slow provider probe covering the distinction.
143 lines
4.8 KiB
TypeScript
143 lines
4.8 KiB
TypeScript
#!/usr/bin/env npx tsx
|
|
|
|
import assert from "node:assert";
|
|
import {
|
|
getDaemonHost,
|
|
normalizeDaemonHost,
|
|
resolveDaemonPassword,
|
|
resolveDaemonTarget,
|
|
} from "../src/utils/client.js";
|
|
import { selectDaemonTarget } from "../src/utils/daemon-target.js";
|
|
import { resolveCliVersion } from "../src/version.js";
|
|
|
|
console.log("=== CLI IPC Target Helpers ===\n");
|
|
|
|
{
|
|
console.log("Test 1: unix hosts resolve to ws+unix URLs");
|
|
const target = resolveDaemonTarget("unix:///tmp/paseo.sock");
|
|
assert.deepStrictEqual(target, {
|
|
type: "ipc",
|
|
url: "ws+unix:///tmp/paseo.sock:/ws",
|
|
socketPath: "/tmp/paseo.sock",
|
|
});
|
|
console.log("✓ unix hosts resolve to ws+unix URLs\n");
|
|
}
|
|
|
|
{
|
|
console.log("Test 1b: bare unix socket paths resolve at the connection boundary");
|
|
const target = resolveDaemonTarget("/tmp/paseo.sock");
|
|
assert.deepStrictEqual(target, {
|
|
type: "ipc",
|
|
url: "ws+unix:///tmp/paseo.sock:/ws",
|
|
socketPath: "/tmp/paseo.sock",
|
|
});
|
|
console.log("✓ bare unix socket paths resolve at the connection boundary\n");
|
|
}
|
|
|
|
{
|
|
console.log("Test 2: pipe hosts preserve the Node socketPath transport form");
|
|
const target = resolveDaemonTarget("pipe://\\\\.\\pipe\\paseo-managed-test");
|
|
assert.deepStrictEqual(target, {
|
|
type: "ipc",
|
|
url: "ws://localhost/ws",
|
|
socketPath: "\\\\.\\pipe\\paseo-managed-test",
|
|
});
|
|
console.log("✓ pipe hosts preserve Node socketPath transport form\n");
|
|
}
|
|
|
|
{
|
|
console.log("Test 3: tcp URI host targets honor ssl=true");
|
|
const target = resolveDaemonTarget("tcp://example.com:6767?ssl=true&password=query-secret");
|
|
assert.deepStrictEqual(target, {
|
|
type: "tcp",
|
|
url: "wss://example.com:6767/ws",
|
|
});
|
|
console.log("✓ tcp URI host targets honor ssl=true\n");
|
|
}
|
|
|
|
{
|
|
console.log("Test 4: tcp URI hosts normalize into canonical direct TCP targets");
|
|
assert.strictEqual(
|
|
normalizeDaemonHost("tcp://Example.com:6767?ssl=true&password=query-secret"),
|
|
"tcp://Example.com:6767?ssl=true&password=query-secret",
|
|
);
|
|
console.log("✓ tcp URI hosts normalize into canonical direct TCP targets\n");
|
|
}
|
|
|
|
{
|
|
console.log("Test 5: local unix socket paths normalize into IPC daemon targets");
|
|
assert.strictEqual(normalizeDaemonHost("/tmp/paseo.sock"), "unix:///tmp/paseo.sock");
|
|
console.log("✓ local unix socket paths normalize into IPC daemon targets\n");
|
|
}
|
|
|
|
{
|
|
console.log("Test 5b: Windows absolute paths are NOT treated as unix sockets");
|
|
assert.strictEqual(normalizeDaemonHost("C:\\Users\\foo\\.paseo\\paseo.sock"), null);
|
|
assert.strictEqual(normalizeDaemonHost("D:\\project\\socket"), null);
|
|
console.log("✓ Windows absolute paths are not treated as unix sockets\n");
|
|
}
|
|
|
|
{
|
|
const target = selectDaemonTarget(
|
|
{ home: "/tmp/selected-home" },
|
|
{ PASEO_HOST: "ignored:12345", PASEO_LISTEN: "ignored:23456" },
|
|
);
|
|
assert.deepStrictEqual(target, { kind: "instance", home: "/tmp/selected-home" });
|
|
assert.strictEqual(getDaemonHost({ target }), "home /tmp/selected-home");
|
|
assert.throws(() => selectDaemonTarget({}, { PASEO_HOME: "/tmp/a", PASEO_HOST: "unused:12345" }));
|
|
}
|
|
|
|
{
|
|
console.log("Test 8: CLI app version resolves for daemon hello compatibility");
|
|
assert.match(resolveCliVersion(), /^\d+\.\d+\.\d+/);
|
|
console.log("✓ CLI app version resolves for daemon hello compatibility\n");
|
|
}
|
|
|
|
{
|
|
console.log("Test 10: daemon password resolution prefers TCP URI query, falls back to env");
|
|
const previousEnv = process.env.PASEO_PASSWORD;
|
|
try {
|
|
delete process.env.PASEO_PASSWORD;
|
|
assert.strictEqual(
|
|
resolveDaemonPassword("tcp://example.com:6767?ssl=true&password=query-secret"),
|
|
"query-secret",
|
|
);
|
|
assert.strictEqual(resolveDaemonPassword("tcp://missing.example:6767"), undefined);
|
|
assert.strictEqual(resolveDaemonPassword("example.com:6767"), undefined);
|
|
|
|
process.env.PASEO_PASSWORD = "env-secret";
|
|
assert.strictEqual(
|
|
resolveDaemonPassword("tcp://example.com:6767?ssl=true&password=query-secret"),
|
|
"query-secret",
|
|
"URI password should take precedence over env var",
|
|
);
|
|
assert.strictEqual(
|
|
resolveDaemonPassword("tcp://missing.example:6767"),
|
|
"env-secret",
|
|
"TCP host without query password should fall back to env var",
|
|
);
|
|
assert.strictEqual(
|
|
resolveDaemonPassword("example.com:6767"),
|
|
"env-secret",
|
|
"Bare host should pick up env var password",
|
|
);
|
|
assert.strictEqual(resolveDaemonPassword("localhost:6767"), "env-secret");
|
|
|
|
process.env.PASEO_PASSWORD = "";
|
|
assert.strictEqual(
|
|
resolveDaemonPassword("localhost:6767"),
|
|
undefined,
|
|
"Empty env var should be treated as unset",
|
|
);
|
|
} finally {
|
|
if (previousEnv === undefined) {
|
|
delete process.env.PASEO_PASSWORD;
|
|
} else {
|
|
process.env.PASEO_PASSWORD = previousEnv;
|
|
}
|
|
}
|
|
console.log("✓ daemon password resolution prefers TCP URI query, falls back to env\n");
|
|
}
|
|
|
|
console.log("=== All CLI IPC target tests passed ===");
|