History

fix(mcp): close project operation races

Julius Marminge committed 2 months ago

Commit e3f2cda1 parent 93b21576 files · +257 −29Browse files

Showing the changes to apps/server/src/sourceControl/SourceControlRepositoryService.test.ts (1 of 6 files). Show all

Unified · Split

apps/server/src/sourceControl/SourceControlRepositoryService.test.ts+65−0
@@ -365,10 +365,75 @@ it.effect("recovers a real completed clone after a lost result and rejects unsaf · 364 unmodified lines
365 365
366 yield* initializeRepository(sourcePath, "source");366 yield* initializeRepository(sourcePath, "source");
367 yield* initializeRepository(otherSourcePath, "other source");367 yield* initializeRepository(otherSourcePath, "other source");
368 yield* fs.writeFileString(`${sourcePath}/CHANGELOG.md`, "second source commit");
369 yield* git.execute({ operation: "test.add.second", cwd: sourcePath, args: ["add", "."] });
370 yield* git.execute({
371 operation: "test.commit.second",
372 cwd: sourcePath,
373 args: ["commit", "-m", "second"],
374 });
368 375
369 const cloned = yield* service.cloneRepository({ remoteUrl: sourcePath, destinationPath });376 const cloned = yield* service.cloneRepository({ remoteUrl: sourcePath, destinationPath });
370 assert.strictEqual(cloned.cwd, destinationPath);377 assert.strictEqual(cloned.cwd, destinationPath);
371 378
379 const headCommit = (yield* git.execute({
380 operation: "test.read.head",
381 cwd: destinationPath,
382 args: ["rev-parse", "HEAD"],
383 })).stdout.trim();
384 const previousCommit = (yield* git.execute({
385 operation: "test.read.previous",
386 cwd: destinationPath,
387 args: ["rev-parse", "HEAD^"],
388 })).stdout.trim();
389 yield* git
390 .execute({
391 operation: "test.remove.remote.head",
392 cwd: destinationPath,
393 args: ["symbolic-ref", "-d", "refs/remotes/origin/HEAD"],
394 })
395 .pipe(Effect.ignore);
396 const existingRemoteRefs = (yield* git.execute({
397 operation: "test.list.remote.refs",
398 cwd: destinationPath,
399 args: ["for-each-ref", "--format=%(refname)", "refs/remotes/origin"],
400 })).stdout
401 .split("\n")
402 .map((line) => line.trim())
403 .filter((line) => line.length > 0);
404 yield* Effect.forEach(
405 existingRemoteRefs,
406 (refName) =>
407 git.execute({
408 operation: "test.remove.remote.ref",
409 cwd: destinationPath,
410 args: ["update-ref", "-d", refName],
411 }),
412 { discard: true },
413 );
414 const noiseRefCommands = Array.from(
415 { length: 1_700 },
416 (_, index) =>
417 `create refs/remotes/origin/noise-${index.toString().padStart(4, "0")} ${previousCommit}`,
418 );
419 yield* git.execute({
420 operation: "test.create.many.remote.refs",
421 cwd: destinationPath,
422 args: ["update-ref", "--stdin"],
423 stdin: [...noiseRefCommands, `create refs/remotes/origin/zzzz-match ${headCommit}`, ""].join(
424 "\n",
425 ),
426 });
427 const oversizedInventory = yield* git
428 .execute({
429 operation: "test.verify.old.remote-ref-boundary",
430 cwd: destinationPath,
431 args: ["for-each-ref", "--format=%(objectname)", "refs/remotes/origin"],
432 maxOutputBytes: 64 * 1024,
433 })
434 .pipe(Effect.flip);
435 assert.instanceOf(oversizedInventory, GitCommandError);
436
372 // Simulate the caller losing the successful clone result before project registration.437 // Simulate the caller losing the successful clone result before project registration.
373 const recovered = yield* service.cloneRepository({ remoteUrl: sourcePath, destinationPath });438 const recovered = yield* service.cloneRepository({ remoteUrl: sourcePath, destinationPath });
374 assert.strictEqual(recovered.cwd, destinationPath);439 assert.strictEqual(recovered.cwd, destinationPath);