Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions tests/fixtures/fake-secret-provider.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,43 @@
import { spawn } from "node:child_process";
import { writeFileSync } from "node:fs";
import { appendFile, writeFile } from "node:fs/promises";
import { connect } from "node:net";

const mode = process.env.MIFTAH_FAKE_MODE ?? "success";
const recordPath = process.env.MIFTAH_FAKE_RECORD_PATH;
const countPath = process.env.MIFTAH_FAKE_COUNT_PATH;
const providerReadyPath = process.env.MIFTAH_FAKE_PROVIDER_READY_PATH;
const providerBarrierPort = process.env.MIFTAH_FAKE_PROVIDER_BARRIER_PORT;

if (providerReadyPath) writeFileSync(providerReadyPath, "provider-entered");

async function waitForProviderBarrier() {
if (providerBarrierPort === undefined) return;
const port = Number(providerBarrierPort);
if (!Number.isSafeInteger(port) || port < 1 || port > 65_535) {
throw new Error("Fake provider received an invalid readiness barrier port");
}

await new Promise((resolve, reject) => {
const socket = connect({ host: "127.0.0.1", port });
let released = false;
const release = () => {
if (released) return;
released = true;
socket.end();
resolve();
};
socket.once("error", reject);
socket.once("data", release);
socket.once("end", release);
socket.once("close", () => {
if (!released) reject(new Error("Readiness barrier closed before release"));
});
});
}

await waitForProviderBarrier();

async function writeRecord(descendantPid) {
if (!recordPath) return;
await writeFile(
Expand Down
103 changes: 92 additions & 11 deletions tests/secret-providers.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { randomUUID } from "node:crypto";
import { spawn } from "node:child_process";
import { chmod, copyFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
import { createServer, type Server, type Socket } from "node:net";
import { delimiter, join, win32 } from "node:path";
import { gzipSync } from "node:zlib";
import { afterAll, describe, expect, it } from "vitest";
Expand Down Expand Up @@ -118,6 +119,59 @@ async function waitForProviderEntered(providerReadyPath: string, description: st
);
}

async function createProviderReadinessBarrier(): Promise<{
server: Server;
port: number;
reached: Promise<void>;
release: () => void;
close: () => Promise<void>;
}> {
let resolveReached!: () => void;
const reached = new Promise<void>((resolve) => {
resolveReached = resolve;
});
let fixtureSocket: Socket | undefined;
const server = createServer((socket) => {
if (fixtureSocket !== undefined) {
socket.destroy();
return;
}
fixtureSocket = socket;
socket.once("error", () => undefined);
resolveReached();
});

await new Promise<void>((resolve, reject) => {
server.once("error", reject);
server.listen(0, "127.0.0.1", () => {
server.off("error", reject);
server.on("error", () => undefined);
resolve();
});
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const address = server.address();
if (address === null || typeof address === "string") {
await new Promise<void>((resolve, reject) => {
server.close((error) => (error ? reject(error) : resolve()));
});
throw new Error("Expected readiness barrier to listen on a TCP port");
}

return {
server,
port: address.port,
reached,
release: () => fixtureSocket?.end("release"),
close: async () => {
fixtureSocket?.destroy();
await new Promise<void>((resolve, reject) => {
server.close((error) => (error ? reject(error) : resolve()));
});
}
};
}

async function readDescendantPid(directory: string): Promise<number> {
let descendantPid: number | undefined;
await waitForCondition(async () => {
Expand Down Expand Up @@ -392,30 +446,57 @@ describe("external secret-reference grammar", () => {
});

describe("secret command runner", () => {
it("keeps provider readiness-barrier server errors handled after startup", async () => {
const barrier = await createProviderReadinessBarrier();
try {
expect(() => barrier.server.emit("error", new Error("test readiness barrier error"))).not.toThrow();
} finally {
await barrier.close();
}
});

it.runIf(process.platform === "win32")(
"preserves a cold Node provider entry marker through Windows helper settlement",
"keeps a cold Node provider pending at a readiness barrier through its Windows helper",
async () => {
await inSandbox(async (directory) => {
const controller = new AbortController();
const providerReadyPath = join(directory, "provider-ready");
const result = await runSecretCommand(
const barrier = await createProviderReadinessBarrier();
const pending = runSecretCommand(
{
executable: process.execPath,
args: [fakeProviderPath],
args: [fakeProviderPath, "readiness-barrier-argument"],
environment: {
...fakeProviderEnvironment(directory, "success"),
MIFTAH_FAKE_PROVIDER_READY_PATH: providerReadyPath
MIFTAH_FAKE_PROVIDER_BARRIER_PORT: `${barrier.port}`
}
},
{ signal: controller.signal }
);
let settled = false;
const settlement = pending.then(
() => {
settled = true;
return "settled" as const;
},
() => {
settled = true;
return "settled" as const;
}
);

// The fixture writes this marker synchronously before stdout and exit;
// runSecretCommand settles only after the contained helper has waited
// for that provider process. This proves the intended ordering without
// asserting a cold-start latency that the production contract does not promise.
expect(result.stdout.toString("utf8")).toBe("fixture-provider-secret");
await expect(readFile(providerReadyPath, "utf8")).resolves.toBe("provider-entered");
try {
expect(await Promise.race([barrier.reached.then(() => "barrier" as const), settlement])).toBe("barrier");
expect(settled).toBe(false);

barrier.release();
const result = await pending;
expect(result.stdout.toString("utf8")).toBe("fixture-provider-secret");
await expect(readFakeRecord(directory)).resolves.toMatchObject({
argv: ["readiness-barrier-argument"]
});
} finally {
await barrier.close();
}
});
}
);
Expand Down