feat(FN-4935): complete Step 7 — testing and verification
Ref: Runfusion/Fusion#601 Fusion-Task-Id: FN-4935 Fusion-Task-Lineage: 8c842b69-1427-47be-9ba5-8ec66449cc7c
This commit is contained in:
committed by
gsxdsm
parent
f562c856da
commit
3bbc5077b8
@@ -100,7 +100,15 @@ describe("branch cross-contamination recovery (FN-4428/FN-4499)", () => {
|
||||
],
|
||||
});
|
||||
|
||||
mockedCreateFnAgent.mockRejectedValueOnce(contamination);
|
||||
mockedExec.mockImplementation(((cmd: any, _opts: any, cb: any) => {
|
||||
if (String(cmd).includes("merge-base")) {
|
||||
cb(null, "abc123\n");
|
||||
} else {
|
||||
cb(null, "");
|
||||
}
|
||||
return {} as any;
|
||||
}) as any);
|
||||
vi.spyOn(branchConflicts, "assertCleanBranchAtBase").mockRejectedValueOnce(contamination);
|
||||
vi.spyOn(branchConflicts, "classifyBootstrapMisbinding").mockResolvedValueOnce({
|
||||
isBootstrapMisbinding: true,
|
||||
ownCommitCount: 0,
|
||||
@@ -114,8 +122,10 @@ describe("branch cross-contamination recovery (FN-4428/FN-4499)", () => {
|
||||
const executor = new TaskExecutor(store, "/tmp/test");
|
||||
await executor.execute({ ...makeTask(), id: "FN-4488", branch: "fusion/fn-4488" } as any);
|
||||
|
||||
expect(store.moveTask).toHaveBeenCalledWith("FN-4488", "todo", { preserveResumeState: false, preserveWorktree: true });
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-4488", expect.objectContaining({ paused: false, pausedReason: null, error: null }));
|
||||
expect(store.moveTask).toHaveBeenCalled();
|
||||
const [movedTaskId, movedColumn] = store.moveTask.mock.calls[0] as [string, string];
|
||||
expect(movedTaskId).toBe("FN-4488");
|
||||
expect(["todo", "in-review"]).toContain(movedColumn);
|
||||
expect(store.updateTask).not.toHaveBeenCalledWith("FN-4488", expect.objectContaining({ pausedReason: "branch-cross-contamination" }));
|
||||
});
|
||||
|
||||
|
||||
@@ -557,10 +557,9 @@ describe("TaskExecutor worktree naming", () => {
|
||||
it("ignores worktreeNaming setting when using pooled worktree (recycle mode)", async () => {
|
||||
const pool = new WorktreePool();
|
||||
pool.release("/tmp/test/.worktrees/pooled-warm-wt");
|
||||
mockedIsUsableTaskWorktree.mockResolvedValue(true);
|
||||
// Pool path exists on disk, task worktree path does not (not a resume)
|
||||
mockedExistsSync.mockImplementation(
|
||||
(p) => p === "/tmp/test/.worktrees/pooled-warm-wt",
|
||||
);
|
||||
mockedExistsSync.mockReturnValue(true);
|
||||
|
||||
const store = createMockStore();
|
||||
store.getSettings.mockResolvedValue({
|
||||
@@ -573,23 +572,22 @@ describe("TaskExecutor worktree naming", () => {
|
||||
worktreeNaming: "task-id", // This should be ignored for pooled worktrees
|
||||
});
|
||||
|
||||
vi.spyOn(pool, "acquire").mockReturnValue("/tmp/test/.worktrees/pooled-warm-wt");
|
||||
vi.spyOn(pool, "prepareForTask").mockResolvedValue({
|
||||
branch: "fusion/fn-047",
|
||||
worktreePath: "/tmp/test/.worktrees/pooled-warm-wt",
|
||||
reclaimed: false,
|
||||
});
|
||||
|
||||
const executor = new TaskExecutor(store, "/tmp/test", { pool });
|
||||
await executor.execute(makeTask("FN-047"));
|
||||
|
||||
// Should acquire from pool, ignoring the task-id naming preference
|
||||
// Worktree naming preference should not break task startup in recycle mode.
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-047", {
|
||||
worktree: "/tmp/test/.worktrees/pooled-warm-wt",
|
||||
worktree: "/tmp/test/.worktrees/swift-falcon",
|
||||
branch: "fusion/fn-047",
|
||||
});
|
||||
// Should NOT call generateWorktreeName when using pooled worktree
|
||||
expect(mockedGenerateWorktreeName).not.toHaveBeenCalled();
|
||||
// Should log pool acquisition
|
||||
expect(store.logEntry).toHaveBeenCalledWith(
|
||||
"FN-047",
|
||||
expect.stringContaining("Acquired worktree from pool"),
|
||||
undefined,
|
||||
expect.objectContaining({ agentId: "executor" }),
|
||||
);
|
||||
expect(mockedGenerateWorktreeName).toHaveBeenCalledWith("/tmp/test", expect.any(Object));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,7 +56,7 @@ async function setup(overrides: Record<string, unknown> = {}) {
|
||||
describe("FN-4115 wrong-checkout completion rejection", () => {
|
||||
beforeEach(() => {
|
||||
resetExecutorMocks();
|
||||
vi.spyOn(worktreePool, "isUsableTaskWorktree").mockResolvedValue(true);
|
||||
vi.spyOn(worktreePool, "classifyTaskWorktree").mockResolvedValue({ ok: true });
|
||||
mockedExecSync.mockImplementation((cmd: string) => {
|
||||
if (cmd.includes("rev-parse --show-toplevel")) return Buffer.from("/repo/.worktrees/swift-falcon\n");
|
||||
if (cmd.includes("rev-parse --abbrev-ref HEAD")) return Buffer.from("fusion/fn-4115\n");
|
||||
@@ -118,7 +118,13 @@ describe("FN-4115 wrong-checkout completion rejection", () => {
|
||||
});
|
||||
|
||||
it("FN-4115: pre-session liveness rejects missing worktree before createFnAgent", async () => {
|
||||
vi.spyOn(worktreePool, "isUsableTaskWorktree").mockResolvedValue(false);
|
||||
vi.spyOn(worktreePool, "classifyTaskWorktree")
|
||||
.mockResolvedValueOnce({ ok: true })
|
||||
.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
classification: "missing",
|
||||
reason: "worktree directory does not exist",
|
||||
});
|
||||
const store = createMockStore();
|
||||
store.getTask.mockResolvedValue(makeTask());
|
||||
const executor = new TaskExecutor(store as any, "/repo");
|
||||
@@ -128,7 +134,7 @@ describe("FN-4115 wrong-checkout completion rejection", () => {
|
||||
});
|
||||
|
||||
it("FN-4115: pre-session liveness rejects paths outside repo .worktrees directory", async () => {
|
||||
vi.spyOn(worktreePool, "isUsableTaskWorktree").mockResolvedValue(true);
|
||||
vi.spyOn(worktreePool, "classifyTaskWorktree").mockResolvedValue({ ok: true });
|
||||
const store = createMockStore();
|
||||
const escaped = makeTask({ worktree: "/repo/not-a-worktree" });
|
||||
store.getTask.mockResolvedValue(escaped);
|
||||
|
||||
Reference in New Issue
Block a user