Public: anyone can read this; the crew can change it.

test/livetriage.test.ts's per-tick caps pass every time on a loaded check machine #4623

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/4579-test-livetriage-test-ts-s-per-tick-caps → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/4579-test-livetriage-test-ts-s-per-tick-caps was merged into main as b519da3.

Review

Sign in to review this change.
1 file changed +27 −17
test/livetriage.test.ts +27 −17
@@ -280,6 +280,8 @@ describe("live triage", () => {
280280 const direction = () => getIssueById(app.db, fresh().directionIssueId!)!;
281281 const lines = () => listComments(app.db, direction().id).map((c) => c.body);
282282 const outsider = async () => {
283 const existing = getUserByName(app.db, "carol");
284 if (existing) return existing;
283285 const made = await createUser(app.db, {
284286 origin: "seed",
285287 trusted: true,
@@ -381,6 +383,9 @@ describe("live triage", () => {
381383 });
382384 });
383385
386 /** The one clock the filing tests age issues from and tick at, so no second read of the time can disagree. */

Good: one constant for aging and ticking. Consider reusing it in the earlier describes too, which still use real time.

387 const CLOCK = new Date("2026-01-01T12:00:00.000Z");
388
384389 describe("live triage files unplaced issues", () => {
385390 let dir: string;
386391 let app: App;
@@ -394,7 +399,7 @@ describe("live triage files unplaced issues", () => {
394399 if (!opened.ok) throw new Error(String(opened.error));
395400 app.db
396401 .query(`UPDATE issue SET created_at = ?2 WHERE id = ?1`)
397 .run(opened.value.id, new Date(Date.now() - age).toISOString());
402 .run(opened.value.id, new Date(CLOCK.getTime() - age).toISOString());
398403 return getIssueById(app.db, opened.value.id)!;
399404 };
400405 const waitsFor = (a: Issue, b: Issue) =>
@@ -442,7 +447,7 @@ describe("live triage files unplaced issues", () => {
442447
443448 test("an issue whose title names a pillar is filed under it, and counted", async () => {
444449 const work = open("Harden P0 sessions");
445 const did = await liveTriage(app, fresh());
450 const did = await liveTriage(app, fresh(), CLOCK);
446451 expect(did.labelled).toBe(1);
447452 expect(waitsFor(umbrella, work)).toBe(true);
448453 expect(labelsFor(app.db, work.id).map((l) => l.name)).toContain("P0 Trust");
@@ -451,32 +456,32 @@ describe("live triage files unplaced issues", () => {
451456
452457 test("a pillar named only in the body files it", async () => {
453458 const work = open("Sessions", "This serves p0 trust.");
454 await liveTriage(app, fresh());
459 await liveTriage(app, fresh(), CLOCK);
455460 expect(waitsFor(umbrella, work)).toBe(true);
456461 });
457462
458463 test("the title wins when title and body name different pillars", async () => {
459464 const other = open("P1 Speed: be quick");
460465 const work = open("Cache P1 pages", "Also touches P0.");
461 await liveTriage(app, fresh());
466 await liveTriage(app, fresh(), CLOCK);
462467 expect(waitsFor(other, work)).toBe(true);
463468 expect(waitsFor(umbrella, work)).toBe(false);
464469 });
465470
466471 test("a bare pillar name in passing does not file it: it goes to Later", async () => {
467472 const work = open("Tell the story of trust", "A story about trust, in passing.");
468 await liveTriage(app, fresh());
473 await liveTriage(app, fresh(), CLOCK);
469474 expect(waitsFor(umbrella, work)).toBe(false);
470475 expect(waitsFor(work, gate)).toBe(true);
471476 });
472477
473478 test("an issue naming none goes behind the Later gate with a comment, once", async () => {
474479 const work = open("Add a colour picker");
475 await liveTriage(app, fresh());
480 await liveTriage(app, fresh(), CLOCK);
476481 expect(waitsFor(work, gate)).toBe(true);
477482 expect(labelsFor(app.db, work.id).map((l) => l.name)).toContain("Later");
478483 expect(notes(work)[0]!.body).toContain("Later gate");
479 const again = await liveTriage(app, fresh());
484 const again = await liveTriage(app, fresh(), CLOCK);
480485 expect(again.labelled).toBe(0);
481486 expect(again.missed).toBe(0);
482487 expect(notes(work)).toHaveLength(1);
@@ -486,7 +491,7 @@ describe("live triage files unplaced issues", () => {
486491 const young = open("Brand new idea", "", 60_000);
487492 const placed = open("Already placed");
488493 link(placed);
489 await liveTriage(app, fresh());
494 await liveTriage(app, fresh(), CLOCK);
490495 expect(waitsFor(young, gate)).toBe(false);
491496 expect(notes(young)).toHaveLength(0);
492497 expect(notes(placed)).toHaveLength(0);
@@ -497,7 +502,7 @@ describe("live triage files unplaced issues", () => {
497502 test("directions, umbrellas and the gate are skipped", async () => {
498503 const direction = open("Direction: keep it small");
499504 app.db.query(`UPDATE repo SET direction_issue_id = ?2 WHERE id = ?1`).run(repo.id, direction.id);
500 await liveTriage(app, fresh());
505 await liveTriage(app, fresh(), CLOCK);
501506 for (const furniture of [direction, umbrella, gate]) expect(notes(furniture)).toHaveLength(0);
502507 expect(waitsFor(direction, gate)).toBe(false);
503508 expect(waitsFor(gate, gate)).toBe(false);
@@ -505,9 +510,9 @@ describe("live triage files unplaced issues", () => {
505510
506511 test("a person who unlinks the gate is not overruled", async () => {
507512 const work = open("Needs thought");
508 await liveTriage(app, fresh());
513 await liveTriage(app, fresh(), CLOCK);
509514 app.db.query(`DELETE FROM issue_dependency WHERE issue_id = ?1`).run(work.id);
510 const did = await liveTriage(app, fresh());
515 const did = await liveTriage(app, fresh(), CLOCK);
511516 expect(waitsFor(work, gate)).toBe(false);
512517 expect(did.labelled).toBe(0);
513518 expect(did.missed).toBe(0);
@@ -549,7 +554,7 @@ describe("live triage where there is little to file under", () => {
549554 });
550555 if (!set.ok) throw new Error(JSON.stringify(set.error));
551556 const repo = () => getRepoById(app.db, made.value.id)!;
552 const old = new Date(Date.now() - 2 * FILE_AFTER_MS).toISOString();
557 const old = new Date(CLOCK.getTime() - 2 * FILE_AFTER_MS).toISOString();
553558 const open = (title: string): Issue => {
554559 const o = openIssue(app, alice, repo(), { title });
555560 if (!o.ok) throw new Error(String(o.error));
@@ -564,26 +569,31 @@ describe("live triage where there is little to file under", () => {
564569
565570 test("pillars but no gate: an unnamed issue is left alone and counted as missed", async () => {
566571 const w = await world("nogate", ["P0 Trust: be safe"], 1);
567 const did = await liveTriage(app, w.repo());
572 const did = await liveTriage(app, w.repo(), CLOCK);
568573 expect(did.labelled).toBe(0);
569574 expect(did.missed).toBe(1);
570575 expect(comments(w.work[0]!)).toBe(0);
571576 expect(labelsFor(app.db, w.work[0]!.id)).toHaveLength(0);
572 expect(app.db.query<{ n: number }, []>(`SELECT COUNT(*) AS n FROM issue_dependency`).get()!.n).toBe(0);
577 const links = app.db
578 .query<{ n: number }, [string]>(
579 `SELECT COUNT(*) AS n FROM issue_dependency d JOIN issue i ON i.id = d.issue_id WHERE i.repo_id = ?1`,
580 )
581 .get(w.repo().id)!.n;
582 expect(links).toBe(0);
573583 });
574584
575585 test("neither pillars nor gate: nothing is filed, counted or written", async () => {
576586 const w = await world("plain", [], 2);
577 expect(await liveTriage(app, w.repo())).toEqual({ closed: 0, folded: 0, labelled: 0, missed: 0 });
587 expect(await liveTriage(app, w.repo(), CLOCK)).toEqual({ closed: 0, folded: 0, labelled: 0, missed: 0 });
578588 for (const issue of w.work) expect(comments(issue)).toBe(0);
579589 });
580590
581591 test("at most 25 issues are filed per tick; the rest are missed, then filed", async () => {
582592 const w = await world("many", ["Later gate: not yet"], MOST_CHANGES + 1);
583 const first = await liveTriage(app, w.repo());
593 const first = await liveTriage(app, w.repo(), CLOCK);
584594 expect(first.labelled).toBe(MOST_CHANGES);
585595 expect(first.missed).toBe(1);
586 const second = await liveTriage(app, w.repo());
596 const second = await liveTriage(app, w.repo(), CLOCK);
587597 expect(second.labelled).toBe(1);
588598 expect(second.missed).toBe(0);
589599 // Twenty-six issues are opened and two ticks run: a loaded check machine must not turn the 5 s default into the verdict.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs