Skip to content

Commit 388cd12

Browse files
committed
test(webapp): run schedule timing benchmarks on demand, not in CI
Wall-clock speedup ratios are single-sample and swing well past the asserted bounds on a shared runner, so the benchmarks now live behind a *.perf.test.ts suffix with their own config and a test:perf script, following the pattern the e2e suites already use. Correctness stays in the ordinary suite. Also splits the malformed-expression test, whose name claimed a lastRun degradation that its assertions did not cover.
1 parent 6865d47 commit 388cd12

5 files changed

Lines changed: 39 additions & 13 deletions

File tree

apps/webapp/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"db:seed:webhooks": "tsx seed-webhook-deliveries.ts",
2525
"upload:sourcemaps": "bash ./upload-sourcemaps.sh",
2626
"test": "vitest --no-file-parallelism",
27+
"test:perf": "vitest --config ./vitest.perf.config.ts --run",
2728
"eval:dev": "evalite watch"
2829
},
2930
"dependencies": {
File renamed without changes.

apps/webapp/test/scheduleTimings.test.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -266,23 +266,26 @@ describe("resolveScheduleTimings", () => {
266266
expect(fresh.lastRun).toEqual(new Date("2024-06-15T00:00:00.000Z"));
267267
});
268268

269-
it("degrades to undefined lastRun for a malformed expression rather than throwing", () => {
270-
const rows = [input({ cron: "0 0 * * *" }), input({ cron: "not a cron" })];
271-
272-
expect(() =>
273-
resolveScheduleTimings([rows[1]], {
274-
phaseSecret: PHASE_SECRET,
275-
includeLastRun: false,
276-
now,
277-
})
278-
).toThrow();
269+
it("throws for a malformed expression, matching the previous behaviour", () => {
270+
for (const includeLastRun of [false, true]) {
271+
expect(() =>
272+
resolveScheduleTimings([input({ cron: "not a cron" })], {
273+
phaseSecret: PHASE_SECRET,
274+
includeLastRun,
275+
now,
276+
})
277+
).toThrow();
278+
}
279+
});
279280

280-
const [valid] = resolveScheduleTimings([rows[0]], {
281+
it("resolves lastRun for a valid expression", () => {
282+
const [valid] = resolveScheduleTimings([input({ cron: "0 0 * * *" })], {
281283
phaseSecret: PHASE_SECRET,
282284
includeLastRun: true,
283285
now,
284286
});
285-
expect(valid.lastRun).toBeDefined();
287+
288+
expect(valid.lastRun).toEqual(new Date("2024-06-15T00:00:00.000Z"));
286289
});
287290

288291
it("honours a caller-supplied schedulePhase over the derived one", () => {

apps/webapp/vitest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default defineConfig({
2727
// *.e2e.test.ts: smoke matrix, run via vitest.e2e.config.ts.
2828
// *.e2e.full.test.ts: full auth suite, runs via vitest.e2e.full.config.ts
2929
// (needs a globalSetup-spawned webapp + Postgres container).
30-
exclude: ["test/**/*.e2e.test.ts", "test/**/*.e2e.full.test.ts"],
30+
exclude: ["test/**/*.e2e.test.ts", "test/**/*.e2e.full.test.ts", "test/**/*.perf.test.ts"],
3131
globals: true,
3232
pool: "forks",
3333
setupFiles: ["./test/setup.ts"], // load apps/webapp/.env

apps/webapp/vitest.perf.config.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { defineConfig } from "vitest/config";
2+
import tsconfigPaths from "vite-tsconfig-paths";
3+
4+
export default defineConfig({
5+
test: {
6+
include: ["test/**/*.perf.test.ts"],
7+
globals: true,
8+
pool: "forks",
9+
/**
10+
* These compare wall-clock timings between two implementations. Single
11+
* samples on a shared CI runner swing by more than the ratios being
12+
* asserted, so they are kept out of the default suite and run on demand
13+
* with `pnpm run test:perf`. Correctness is covered by the ordinary
14+
* suites; these exist to show the shape of the win and to catch a
15+
* large regression locally.
16+
*/
17+
fileParallelism: false,
18+
testTimeout: 120_000,
19+
},
20+
// @ts-ignore
21+
plugins: [tsconfigPaths({ projects: ["./tsconfig.json"] })],
22+
});

0 commit comments

Comments
 (0)