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

"RepoSource: one repository, two places to read it from > a mirror reports its stages in order and ends holding the repo" passes every time on a loaded check machine #5399

Merged opened this

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

Merged

scout/forge:scout/5394-reposource-one-repository-two-places-to → main 2 commits fork 1 thread · 1 unresolved

  • Merged. scout/5394-reposource-one-repository-two-places-to was merged into main as 60f5e7f.

Review

Sign in to review this change.
2 files changed +21 −2
test/fake-origin.ts +9
@@ -210,6 +210,8 @@ export interface FakeState {
210210 refuseFork: string;
211211 /** Hold every issue-search answer this long before sending it. */
212212 searchDelayMs: number;
213 /** When set, the labels list waits for it: a test pins a mirror mid-flight. */
214 holdLabels?: Promise<void> | undefined;
213215 nextId: number;
214216 /** The OAuth endpoints, when a test wants the connect flows. */
215217 oauth?: FakeOAuth;
@@ -286,6 +288,13 @@ export function serveFakeForge(state: FakeState): FakeForge {
286288 body: bodyText,
287289 });
288290
291 if (
292 state.holdLabels !== undefined &&
293 request.method === "GET" &&
294 url.pathname.endsWith("/labels")
295 )
296 await state.holdLabels;
297
289298 // The OAuth endpoints hang off the web origin and take no bearer
290299 // token, so they are answered before the API's auth check.
291300 if (state.oauth !== undefined) {
test/view-source.test.ts +12 −2
@@ -532,21 +532,31 @@ describe("RepoSource: one repository, two places to read it from", () => {
532532 // ---- mirroring, with something to watch ----
533533
534534 test("a mirror reports its stages in order and ends holding the repo", async () => {
535 // Pin the job before its label import until we are subscribed: a
536 // subscriber replays only the stage the job is on, so on a loaded machine
537 // a job that raced ahead of the subscription would show just "done".
538 let release = (): void => {};
539 fake.state.holdLabels = new Promise<void>((resolve) => {
540 release = resolve;
541 });
535542 const started = await api(`/api/v1/user/origins/${originId}/mirror`, {
536543 method: "POST",
537544 body: JSON.stringify({ fullName: "octo/widgets" }),
538545 });
539546 expect(started.status).toBe(202);
540 const job = (await read<{ job: { id: string; stage: string } }>(started))
547 const job = (await read<{ job: { id: string; stage: MirrorStage } }>(started))
541548 .job;
542549 expect(job.stage).toBe("creating");
543550
544 const seen: MirrorStage[] = [];
551 // "creating" was observed in the 202; the subscription sees the rest.
552 const seen: MirrorStage[] = [job.stage];
545553 const stop = subscribe(job.id, (update) => {
546554 if (seen[seen.length - 1] !== update.stage) seen.push(update.stage);
547555 });
556 release();
548557 const finished = await settled(job.id);

Move this reset into afterEach or a finally: if settled() or an earlier expect throws, holdLabels stays set and any later label GET in this file hangs.

549558 stop();
559 fake.state.holdLabels = undefined;
550560
551561 expect(finished?.stage).toBe("done");
552562 expect(finished?.repo?.name).toBe("widgets");

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs