Merge pull request 'test: give Core's import-safety tests a timeout that holds under full verify load' (#75) from test/import-safety-timeouts into main
CI / verify (push) Successful in 1m3s
CI / infrastructure-smoke (push) Successful in 28s
CI / migration-smoke (push) Successful in 1m48s
CI / image-build (push) Successful in 12s
CI / deploy-smoke (same-origin) (push) Successful in 48s
CI / deploy-smoke (split) (push) Successful in 1m22s
CI / verify (push) Successful in 1m3s
CI / infrastructure-smoke (push) Successful in 28s
CI / migration-smoke (push) Successful in 1m48s
CI / image-build (push) Successful in 12s
CI / deploy-smoke (same-origin) (push) Successful in 48s
CI / deploy-smoke (split) (push) Successful in 1m22s
Reviewed-on: https://git.riverofglorymn.org/River_of_Glory_Church/Ekklesia/pulls/75 Reviewed-by: The_River <[email protected]>
This commit was merged in pull request #75.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { IMPORT_SAFETY_TEST_TIMEOUT_MS } from "./support/import-safety.js";
|
||||||
|
|
||||||
const poolConstructor = vi.hoisted(() => vi.fn());
|
const poolConstructor = vi.hoisted(() => vi.fn());
|
||||||
|
|
||||||
@@ -7,7 +8,9 @@ vi.mock("pg", () => ({ Pool: poolConstructor }));
|
|||||||
describe("bootstrap-platform-owner CLI import safety", () => {
|
describe("bootstrap-platform-owner CLI import safety", () => {
|
||||||
const originalEnv = { ...process.env };
|
const originalEnv = { ...process.env };
|
||||||
|
|
||||||
it("does not read DATABASE_URL, connect to PostgreSQL, or run bootstrap merely by importing the module", async () => {
|
it(
|
||||||
|
"does not read DATABASE_URL, connect to PostgreSQL, or run bootstrap merely by importing the module",
|
||||||
|
async () => {
|
||||||
delete process.env.DATABASE_URL;
|
delete process.env.DATABASE_URL;
|
||||||
|
|
||||||
// Under Vitest, process.argv[1] is never this file's own path, so isDirectExecution() is
|
// Under Vitest, process.argv[1] is never this file's own path, so isDirectExecution() is
|
||||||
@@ -18,5 +21,7 @@ describe("bootstrap-platform-owner CLI import safety", () => {
|
|||||||
expect(poolConstructor).not.toHaveBeenCalled();
|
expect(poolConstructor).not.toHaveBeenCalled();
|
||||||
|
|
||||||
process.env = originalEnv;
|
process.env = originalEnv;
|
||||||
});
|
},
|
||||||
|
IMPORT_SAFETY_TEST_TIMEOUT_MS,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { IMPORT_SAFETY_TEST_TIMEOUT_MS } from "./support/import-safety.js";
|
||||||
|
|
||||||
const poolConstructor = vi.hoisted(() => vi.fn());
|
const poolConstructor = vi.hoisted(() => vi.fn());
|
||||||
|
|
||||||
@@ -7,7 +8,9 @@ vi.mock("pg", () => ({ Pool: poolConstructor }));
|
|||||||
describe("create-initial-owner CLI import safety", () => {
|
describe("create-initial-owner CLI import safety", () => {
|
||||||
const originalEnv = { ...process.env };
|
const originalEnv = { ...process.env };
|
||||||
|
|
||||||
it("does not read DATABASE_URL, connect to PostgreSQL, or create anything merely by importing the module", async () => {
|
it(
|
||||||
|
"does not read DATABASE_URL, connect to PostgreSQL, or create anything merely by importing the module",
|
||||||
|
async () => {
|
||||||
delete process.env.DATABASE_URL;
|
delete process.env.DATABASE_URL;
|
||||||
|
|
||||||
// Under Vitest, process.argv[1] is never this file's own path, so isDirectExecution() is false
|
// Under Vitest, process.argv[1] is never this file's own path, so isDirectExecution() is false
|
||||||
@@ -18,7 +21,9 @@ describe("create-initial-owner CLI import safety", () => {
|
|||||||
expect(poolConstructor).not.toHaveBeenCalled();
|
expect(poolConstructor).not.toHaveBeenCalled();
|
||||||
|
|
||||||
process.env = originalEnv;
|
process.env = originalEnv;
|
||||||
});
|
},
|
||||||
|
IMPORT_SAFETY_TEST_TIMEOUT_MS,
|
||||||
|
);
|
||||||
|
|
||||||
it("reads no environment variable for the password", async () => {
|
it("reads no environment variable for the password", async () => {
|
||||||
// The password is prompted for or read from standard input; it is deliberately never taken from
|
// The password is prompted for or read from standard input; it is deliberately never taken from
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { IMPORT_SAFETY_TEST_TIMEOUT_MS } from "./support/import-safety.js";
|
||||||
|
|
||||||
const discoverModules = vi.fn();
|
const discoverModules = vi.fn();
|
||||||
const discoverModuleSchemas = vi.fn();
|
const discoverModuleSchemas = vi.fn();
|
||||||
@@ -22,7 +23,9 @@ vi.mock("../src/migrations/index.js", async (importOriginal) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
describe("Doctor import safety", () => {
|
describe("Doctor import safety", () => {
|
||||||
it("does not discover, connect, plan, or print when imported", async () => {
|
it(
|
||||||
|
"does not discover, connect, plan, or print when imported",
|
||||||
|
async () => {
|
||||||
const log = vi.spyOn(console, "log").mockImplementation(() => undefined);
|
const log = vi.spyOn(console, "log").mockImplementation(() => undefined);
|
||||||
const error = vi.spyOn(console, "error").mockImplementation(() => undefined);
|
const error = vi.spyOn(console, "error").mockImplementation(() => undefined);
|
||||||
|
|
||||||
@@ -41,5 +44,7 @@ describe("Doctor import safety", () => {
|
|||||||
|
|
||||||
log.mockRestore();
|
log.mockRestore();
|
||||||
error.mockRestore();
|
error.mockRestore();
|
||||||
});
|
},
|
||||||
|
IMPORT_SAFETY_TEST_TIMEOUT_MS,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { IMPORT_SAFETY_TEST_TIMEOUT_MS } from "./support/import-safety.js";
|
||||||
|
|
||||||
const readdir = vi.fn();
|
const readdir = vi.fn();
|
||||||
const readFile = vi.fn();
|
const readFile = vi.fn();
|
||||||
@@ -14,7 +15,9 @@ vi.mock("node:fs/promises", async (importOriginal) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
describe("module HTTP contract and runtime import safety", () => {
|
describe("module HTTP contract and runtime import safety", () => {
|
||||||
it("performs no filesystem I/O merely by importing the module runtime or the module-http contract", async () => {
|
it(
|
||||||
|
"performs no filesystem I/O merely by importing the module runtime or the module-http contract",
|
||||||
|
async () => {
|
||||||
await import("../src/modules/index.js");
|
await import("../src/modules/index.js");
|
||||||
await import("@ekklesia/contracts");
|
await import("@ekklesia/contracts");
|
||||||
|
|
||||||
@@ -22,5 +25,7 @@ describe("module HTTP contract and runtime import safety", () => {
|
|||||||
expect(readFile).not.toHaveBeenCalled();
|
expect(readFile).not.toHaveBeenCalled();
|
||||||
expect(realpath).not.toHaveBeenCalled();
|
expect(realpath).not.toHaveBeenCalled();
|
||||||
expect(stat).not.toHaveBeenCalled();
|
expect(stat).not.toHaveBeenCalled();
|
||||||
});
|
},
|
||||||
|
IMPORT_SAFETY_TEST_TIMEOUT_MS,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* The per-test timeout for Core's import-safety tests, and only those.
|
||||||
|
*
|
||||||
|
* Each of these tests proves that importing a module does nothing (no I/O, no connection, no output)
|
||||||
|
* by performing a cold dynamic `import()` of a large Core source graph inside the test body. Vitest
|
||||||
|
* transforms and evaluates that whole graph on demand, and that work is CPU-bound. An ordinary test
|
||||||
|
* file's own top-level imports run before its tests start and fall under no per-test timeout; these
|
||||||
|
* deliberately do not, so the cost lands inside Vitest's default 5-second test timeout.
|
||||||
|
*
|
||||||
|
* Alone they take about 0.7–1.2 s. During a full `pnpm verify`, Turbo runs every package's suite at
|
||||||
|
* once and the CPU is saturated. Reproduced locally (six cores, Core's suite alongside five other
|
||||||
|
* packages' suites), the same tests took 3.0–5.4 s, and so timed out intermittently.
|
||||||
|
*
|
||||||
|
* 30 seconds is about five times the slowest time measured under load, which leaves room for slower
|
||||||
|
* shared CI runners. It matches the repository's integration-test timeout. It is still bounded, so a
|
||||||
|
* module that genuinely hangs while being imported, for example on a network call, still fails. The
|
||||||
|
* assertions themselves are unchanged: these tests fail on what an import does, never on speed.
|
||||||
|
*/
|
||||||
|
export const IMPORT_SAFETY_TEST_TIMEOUT_MS = 30_000;
|
||||||
Reference in New Issue
Block a user