Skip to content
File

Blob: tests/worker/dispatch/shared/run-environment/pinned-checkout.depth.test.ts

typescript238 lines
1import { describe, expect, it } from "vitest";
2 
3import { CommitSha, type CommitSha as CommitShaType } from "@/contracts";
4import { prepareExecutionEnvironment } from "@/worker/dispatch/shared/run-environment";
5 
6import {
7 INVALID_REPO_CONFIG,
8 VALID_REPO_CONFIG,
9 createExecResult,
10 createHarness,
11 createLeaseStub,
12} from "../../../../helpers/run-environment";
13 
14const expectPinnedCheckoutFailure = async (
15 commitSha: CommitShaType,
16 options: {
17 projectIdValue: string;
18 runIdValue: string;
19 configContent?: string;
20 execImpl: (command: string, events: string[]) => ReturnType<typeof createExecResult>;
21 },
22) => {
23 const { context, events, projectId, recordRunResolvedCommit, runId, sandbox } = createHarness({
24 projectIdValue: options.projectIdValue,
25 runIdValue: options.runIdValue,
26 snapshotCommitSha: commitSha,
27 configContent: options.configContent ?? INVALID_REPO_CONFIG,
28 execImpl: (command) => options.execImpl(command, events),
29 });
30 
31 return {
32 context,
33 events,
34 projectId,
35 recordRunResolvedCommit,
36 runId,
37 sandbox,
38 };
39};
40 
41describe("run environment preparation", () => {
42 describe("pinned checkout depth handling", () => {
43 it("deepens pinned checkouts by exact SHA after loading repo config", async () => {
44 const pinnedCommitSha = CommitSha.assertDecode("4444444444444444444444444444444444444444");
45 let catFileChecks = 0;
46 let checkedOutPinnedCommit = false;
47 
48 const { context, events, projectId, recordRunResolvedCommit, runId, sandbox } = await expectPinnedCheckoutFailure(
49 pinnedCommitSha,
50 {
51 projectIdValue: "prj_2222222222222222222222",
52 runIdValue: "run_2222222222222222222222",
53 configContent: VALID_REPO_CONFIG,
54 execImpl: (command, events) => {
55 if (command.includes(" clone --branch ") || command.includes(" origin 'main'")) {
56 throw new Error(`Pinned checkout should not depend on branch refs: ${command}`);
57 }
58 
59 if (command.startsWith("git init ")) {
60 events.push("init");
61 return createExecResult();
62 }
63 
64 if (command.includes("remote add origin")) {
65 events.push("remote-add");
66 return createExecResult();
67 }
68 
69 if (command.includes(`fetch --depth=1 --update-shallow origin '${pinnedCommitSha}'`)) {
70 events.push("fetch-depth-1");
71 return createExecResult();
72 }
73 
74 if (command.includes("cat-file -e")) {
75 catFileChecks += 1;
76 events.push(`cat-file-${catFileChecks}`);
77 return createExecResult({
78 success: catFileChecks >= 2,
79 stderr: catFileChecks >= 2 ? "" : "fatal: Not a valid object name",
80 });
81 }
82 
83 if (command.includes(`fetch --depth=3 --update-shallow origin '${pinnedCommitSha}'`)) {
84 events.push("fetch-depth-3");
85 return createExecResult();
86 }
87 
88 if (command.includes("rev-parse --is-shallow-repository")) {
89 events.push("check-shallow");
90 return createExecResult({
91 stdout: "true\n",
92 });
93 }
94 
95 if (command.includes("checkout --detach")) {
96 expect(command).toContain(pinnedCommitSha);
97 checkedOutPinnedCommit = true;
98 events.push("checkout-detached");
99 return createExecResult();
100 }
101 
102 if (command.includes("rev-parse HEAD")) {
103 events.push("rev-parse");
104 return createExecResult({
105 stdout: `${checkedOutPinnedCommit ? pinnedCommitSha : pinnedCommitSha}\n`,
106 });
107 }
108 
109 throw new Error(`Unexpected exec command: ${command}`);
110 },
111 },
112 );
113 
114 await expect(prepareExecutionEnvironment(context, createLeaseStub())).resolves.toEqual({
115 repoConfig: expect.objectContaining({
116 checkout: expect.objectContaining({ depth: 3 }),
117 }),
118 workingDirectory: "/workspace/repo",
119 });
120 
121 expect(recordRunResolvedCommit).toHaveBeenCalledWith({
122 projectId,
123 runId,
124 commitSha: pinnedCommitSha,
125 });
126 expect(catFileChecks).toBe(2);
127 expect(events).toContain("fetch-depth-1");
128 expect(events).toContain("fetch-depth-3");
129 expect(events.indexOf("record-run-resolved-commit")).toBeLessThan(events.indexOf("read-file"));
130 expect(events.indexOf("fetch-depth-3")).toBeGreaterThan(events.indexOf("read-file"));
131 expect(events.indexOf("checkout-detached")).toBeGreaterThan(events.indexOf("cat-file-2"));
132 expect(sandbox.deleteSession).toHaveBeenCalledWith("checkout-session");
133 expect(context.state.session).toMatchObject({ id: "run-session" });
134 });
135 
136 it("skips pinned depth expansion after a full-history fallback", async () => {
137 const rewrittenHeadSha = CommitSha.assertDecode("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
138 const pinnedCommitSha = CommitSha.assertDecode("cccccccccccccccccccccccccccccccccccccccc");
139 let catFileChecks = 0;
140 let checkedOutPinnedCommit = false;
141 
142 const { context, events, projectId, recordRunResolvedCommit, runId, sandbox } = await expectPinnedCheckoutFailure(
143 pinnedCommitSha,
144 {
145 projectIdValue: "prj_7777777777777777777777",
146 runIdValue: "run_7777777777777777777777",
147 configContent: VALID_REPO_CONFIG,
148 execImpl: (command, events) => {
149 if (command.includes(" clone --branch ") || command.includes(" origin 'main'")) {
150 throw new Error(`Pinned checkout should not depend on branch refs: ${command}`);
151 }
152 
153 if (command.startsWith("git init ")) {
154 events.push("init");
155 return createExecResult();
156 }
157 
158 if (command.includes("remote add origin")) {
159 events.push("remote-add");
160 return createExecResult();
161 }
162 
163 if (command.includes("cat-file -e")) {
164 catFileChecks += 1;
165 events.push(`cat-file-${catFileChecks}`);
166 return createExecResult({
167 success: events.includes("fetch-exact-sha"),
168 stderr: events.includes("fetch-exact-sha") ? "" : "fatal: Not a valid object name",
169 });
170 }
171 
172 if (command.includes(`fetch --depth=1 --update-shallow origin '${pinnedCommitSha}'`)) {
173 events.push("fetch-depth-1");
174 return createExecResult({
175 success: false,
176 stderr: "fatal: dumb http transport does not support shallow capabilities",
177 });
178 }
179 
180 if (command.includes(`fetch --depth=3 --update-shallow origin '${pinnedCommitSha}'`)) {
181 throw new Error(`Pinned depth expansion should be skipped after full fallback: ${command}`);
182 }
183 
184 if (command.includes(`fetch origin '${pinnedCommitSha}'`)) {
185 events.push("fetch-exact-sha");
186 return createExecResult();
187 }
188 
189 if (command.includes("rev-parse --is-shallow-repository")) {
190 events.push("check-shallow");
191 return createExecResult({
192 stdout: "false\n",
193 });
194 }
195 
196 if (command.includes("checkout --detach")) {
197 expect(command).toContain(pinnedCommitSha);
198 checkedOutPinnedCommit = true;
199 events.push("checkout-detached");
200 return createExecResult();
201 }
202 
203 if (command.includes("rev-parse HEAD")) {
204 events.push("rev-parse");
205 return createExecResult({
206 stdout: `${checkedOutPinnedCommit ? pinnedCommitSha : rewrittenHeadSha}\n`,
207 });
208 }
209 
210 throw new Error(`Unexpected exec command: ${command}`);
211 },
212 },
213 );
214 
215 await expect(prepareExecutionEnvironment(context, createLeaseStub())).resolves.toEqual({
216 repoConfig: expect.objectContaining({
217 checkout: expect.objectContaining({ depth: 3 }),
218 }),
219 workingDirectory: "/workspace/repo",
220 });
221 
222 expect(recordRunResolvedCommit).toHaveBeenCalledWith({
223 projectId,
224 runId,
225 commitSha: pinnedCommitSha,
226 });
227 expect(events.indexOf("fetch-exact-sha")).toBeGreaterThan(events.indexOf("fetch-depth-1"));
228 expect(events.indexOf("cat-file-2")).toBeGreaterThan(events.indexOf("fetch-exact-sha"));
229 expect(events.indexOf("record-run-resolved-commit")).toBeLessThan(events.indexOf("read-file"));
230 expect(events.indexOf("check-shallow")).toBeGreaterThan(events.indexOf("read-file"));
231 expect(events).not.toContain("fetch-depth-3");
232 expect(events.indexOf("checkout-detached")).toBeGreaterThan(events.indexOf("cat-file-2"));
233 expect(sandbox.deleteSession).toHaveBeenCalledWith("checkout-session");
234 expect(context.state.session).toMatchObject({ id: "run-session" });
235 });
236 });
237});