mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
test(integration): size the all-time count case to its measured cost
The rollup parity case writes over half a million readings and folds them into DAY buckets: about 35 s on a CI runner alone. Run beside two other heavy files on the same Postgres it took 1.7 times as long and crossed the 60 s default. Nothing in the case waits on a lock: its advisory locks are scoped to the worker's own database, and the measurement with the database capped at two CPUs (14.6 s alone, 25.3 s beside the sharing matrix and the restore memory test) shows plain contention. The case gets a 150 s budget, twice the contended estimate. HEALTHLOG_INTEGRATION_PG_CPUS caps the database container so a CI runner's contention can be reproduced locally.
This commit is contained in:
1 parent
7248347188
commit
b6e9eb98f7
3 files changed
+27
-10
No files matched your search
@@ -119,7 +119,9 @@ Each Vitest worker clones it on its first file (`CREATE DATABASE … TEMPLATE`,
|
||||
see `tests/integration/worker-database.ts`), so files run in parallel without
|
||||
seeing each other's rows, advisory locks or queue schema. The worker count
|
||||
follows the host (half the cores, at most eight) unless
|
||||
`HEALTHLOG_INTEGRATION_WORKERS` pins it; CI uses three.
|
||||
`HEALTHLOG_INTEGRATION_WORKERS` pins it; CI uses three. To reproduce a CI runner's
|
||||
contention on a larger machine, cap the database container with
|
||||
`HEALTHLOG_INTEGRATION_PG_CPUS=2`.
|
||||
|
||||
`truncateAllTables` empties every table the migrations created and puts back
|
||||
the rows they seed (the mood-tag and symptom catalogues), so a test starts
|
||||
|
||||
@@ -335,5 +335,12 @@ describe("dashboard all-time counts — parity with the live count", () => {
|
||||
expect(legacy.get("PULSE")).toBeGreaterThan(500_000);
|
||||
expect(legacy.get("WEIGHT")).toBe(5);
|
||||
expect(legacy.get("BLOOD_GLUCOSE")).toBe(2);
|
||||
});
|
||||
// Over half a million rows written and folded into DAY buckets: about
|
||||
// 35 s on a CI runner when the file ran alone. With three files sharing
|
||||
// the runner's Postgres it took 1.7 times as long (measured with the
|
||||
// database capped at two CPUs, HEALTHLOG_INTEGRATION_PG_CPUS=2: 14.6 s
|
||||
// alone, 25.3 s beside the sharing matrix and the restore memory test),
|
||||
// past the suite's 60 s default. The work is the point of the case, so
|
||||
// the budget is sized to it: twice the contended estimate.
|
||||
}, 150_000);
|
||||
});
|
||||
@@ -44,7 +44,7 @@ const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const PROJECT_ROOT = resolve(__dirname, "..", "..");
|
||||
|
||||
let container: StartedPostgreSqlContainer | null = null;
|
||||
let started: StartedPostgreSqlContainer | null = null;
|
||||
|
||||
declare module "vitest" {
|
||||
export interface ProvidedContext {
|
||||
@@ -56,7 +56,7 @@ declare module "vitest" {
|
||||
export default async function setup(
|
||||
project: TestProject,
|
||||
): Promise<() => Promise<void>> {
|
||||
container = await new PostgreSqlContainer("postgres:16-alpine")
|
||||
let container = new PostgreSqlContainer("postgres:16-alpine")
|
||||
.withDatabase(TEMPLATE_DATABASE)
|
||||
.withUsername("healthlog")
|
||||
.withPassword("healthlog")
|
||||
@@ -74,10 +74,18 @@ export default async function setup(
|
||||
"full_page_writes=off",
|
||||
"-c",
|
||||
"max_connections=400",
|
||||
])
|
||||
.start();
|
||||
]);
|
||||
// A CPU quota for the database container, to reproduce a CI runner's
|
||||
// contention on a larger machine: HEALTHLOG_INTEGRATION_PG_CPUS=2.
|
||||
const cpus = Number.parseFloat(
|
||||
process.env.HEALTHLOG_INTEGRATION_PG_CPUS ?? "",
|
||||
);
|
||||
if (Number.isFinite(cpus) && cpus > 0) {
|
||||
container = container.withResourcesQuota({ cpu: cpus });
|
||||
}
|
||||
started = await container.start();
|
||||
|
||||
const url = container.getConnectionUri() + "?schema=public&pgbouncer=false";
|
||||
const url = started.getConnectionUri() + "?schema=public&pgbouncer=false";
|
||||
process.env.DATABASE_URL = url;
|
||||
|
||||
// The explicit child environment keeps Prisma CLI on the same container.
|
||||
@@ -91,9 +99,9 @@ export default async function setup(
|
||||
project.provide("integrationDatabasePlan", await readTemplate(url));
|
||||
|
||||
return async () => {
|
||||
if (container) {
|
||||
await container.stop({ remove: true });
|
||||
container = null;
|
||||
if (started) {
|
||||
await started.stop({ remove: true });
|
||||
started = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user