mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-11-01 22:08:18 +00:00
Migrate CLI E2E tests to Node.js 26
Run the CLI subprocess suites and benchmark tools as native TypeScript with node:test, and move them under test/e2e-cli. Update CI and Compose runners, run local smoke tests on Linux, macOS, and Windows, and collect source-mapped CLI coverage with c8.
This commit is contained in:
1 parent
a0987016bb
commit
2433d117c2
91 files changed
+2219
-1615
No files matched your search
@@ -0,0 +1,59 @@
|
||||
import { createConnection, createServer } from "node:net";
|
||||
|
||||
type WaitForPortOptions = { timeoutMs?: number; intervalMs?: number; connectTimeoutMs?: number };
|
||||
|
||||
async function connectWithTimeout(hostname: string, port: number, timeoutMs: number): Promise<void> {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const socket = createConnection({ host: hostname, port });
|
||||
socket.setTimeout(timeoutMs, () => socket.destroy(new Error(`connect timeout after ${timeoutMs}ms`)));
|
||||
socket.once("error", reject);
|
||||
socket.once("connect", () => {
|
||||
socket.destroy();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function waitForPort(hostname: string, port: number, options: WaitForPortOptions = {}): Promise<void> {
|
||||
const timeoutMs = options.timeoutMs ?? 15000;
|
||||
const intervalMs = options.intervalMs ?? 250;
|
||||
const started = Date.now();
|
||||
let lastError: unknown;
|
||||
while (Date.now() - started < timeoutMs) {
|
||||
try {
|
||||
await connectWithTimeout(hostname, port, options.connectTimeoutMs ?? 1000);
|
||||
return;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
`Port ${hostname}:${port} did not become ready within ${timeoutMs}ms` +
|
||||
(lastError ? ` (last error: ${String(lastError)})` : "")
|
||||
);
|
||||
}
|
||||
|
||||
export async function getFreePort(hostname = "127.0.0.1"): Promise<number> {
|
||||
const server = createServer();
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
server.once("error", reject);
|
||||
server.listen(0, hostname, resolve);
|
||||
});
|
||||
const address = server.address();
|
||||
await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())));
|
||||
if (!address || typeof address === "string") throw new Error("The listener did not bind a TCP port");
|
||||
return address.port;
|
||||
}
|
||||
|
||||
export async function getOptimalLoopbackIp(): Promise<string> {
|
||||
for (const hostname of ["127.0.0.1", "::1"]) {
|
||||
try {
|
||||
await getFreePort(hostname);
|
||||
return hostname;
|
||||
} catch {
|
||||
/* Try the other loopback family. */
|
||||
}
|
||||
}
|
||||
return "127.0.0.1";
|
||||
}
|
||||
Reference in new issue
Block a user