test(FN-5052): complete Step 6 — cover self-healing autoMerge gating
Fusion-Task-Id: FN-5052 Fusion-Task-Lineage: 607cd9e6-e4d0-4572-b183-8253d127209f
This commit is contained in:
committed by
gsxdsm
parent
32f2948906
commit
22c3acf2e0
@@ -9,6 +9,7 @@ function createStore(task: Task, settings: Record<string, unknown> = {}): TaskSt
|
|||||||
|
|
||||||
(emitter as any).__auditEvents = auditEvents;
|
(emitter as any).__auditEvents = auditEvents;
|
||||||
(emitter as any).getSettings = vi.fn().mockResolvedValue({
|
(emitter as any).getSettings = vi.fn().mockResolvedValue({
|
||||||
|
autoMerge: true,
|
||||||
globalPause: false,
|
globalPause: false,
|
||||||
enginePaused: false,
|
enginePaused: false,
|
||||||
taskStuckTimeoutMs: 60_000,
|
taskStuckTimeoutMs: 60_000,
|
||||||
|
|||||||
@@ -4626,7 +4626,7 @@ describe("SelfHealingManager", () => {
|
|||||||
it("logs FN-4110 stale transient merge status once without moving task", async () => {
|
it("logs FN-4110 stale transient merge status once without moving task", async () => {
|
||||||
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
||||||
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000 });
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: true });
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([staleMergingTask()]);
|
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([staleMergingTask()]);
|
||||||
|
|
||||||
const result = await managerWithRecovery.surfaceInReviewStalls();
|
const result = await managerWithRecovery.surfaceInReviewStalls();
|
||||||
@@ -4641,10 +4641,27 @@ describe("SelfHealingManager", () => {
|
|||||||
managerWithRecovery.stop();
|
managerWithRecovery.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("skips entirely when autoMerge is disabled", async () => {
|
||||||
|
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
||||||
|
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||||
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: false });
|
||||||
|
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([staleMergingTask()]);
|
||||||
|
|
||||||
|
expect(await managerWithRecovery.surfaceInReviewStalls()).toBe(0);
|
||||||
|
expect(store.logEntry).not.toHaveBeenCalledWith(
|
||||||
|
"FN-4110",
|
||||||
|
expect.stringContaining("In-review stall surfaced ["),
|
||||||
|
);
|
||||||
|
expect(store.recordRunAuditEvent).not.toHaveBeenCalledWith(expect.objectContaining({
|
||||||
|
mutationType: "task:in-review-stall-deadlock-disposed",
|
||||||
|
}));
|
||||||
|
managerWithRecovery.stop();
|
||||||
|
});
|
||||||
|
|
||||||
it("deduplicates same code inside stuck-timeout window", async () => {
|
it("deduplicates same code inside stuck-timeout window", async () => {
|
||||||
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
||||||
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000 });
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: true });
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||||
staleMergingTask({
|
staleMergingTask({
|
||||||
log: [{
|
log: [{
|
||||||
@@ -4662,7 +4679,7 @@ describe("SelfHealingManager", () => {
|
|||||||
it("re-logs after window expiry and on code transitions", async () => {
|
it("re-logs after window expiry and on code transitions", async () => {
|
||||||
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
||||||
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000 });
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: true });
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>)
|
(store.listTasks as ReturnType<typeof vi.fn>)
|
||||||
.mockResolvedValueOnce([
|
.mockResolvedValueOnce([
|
||||||
staleMergingTask({
|
staleMergingTask({
|
||||||
@@ -4699,7 +4716,7 @@ describe("SelfHealingManager", () => {
|
|||||||
getActiveMergeTaskId: () => "FN-ACTIVE",
|
getActiveMergeTaskId: () => "FN-ACTIVE",
|
||||||
getExecutingTaskIds: () => new Set(["FN-EXEC"]),
|
getExecutingTaskIds: () => new Set(["FN-EXEC"]),
|
||||||
});
|
});
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000 });
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: true });
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||||
staleMergingTask({ id: "FN-CYCLE", updatedAt: "2026-01-01T00:10:00.000Z" }),
|
staleMergingTask({ id: "FN-CYCLE", updatedAt: "2026-01-01T00:10:00.000Z" }),
|
||||||
staleMergingTask({ id: "FN-PAUSED", paused: true }),
|
staleMergingTask({ id: "FN-PAUSED", paused: true }),
|
||||||
@@ -4720,6 +4737,7 @@ describe("SelfHealingManager", () => {
|
|||||||
const reason = "task is marked 'failed': Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
const reason = "task is marked 'failed': Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({
|
||||||
taskStuckTimeoutMs: 60_000,
|
taskStuckTimeoutMs: 60_000,
|
||||||
|
autoMerge: true,
|
||||||
inReviewStallDeadlockThreshold: 3,
|
inReviewStallDeadlockThreshold: 3,
|
||||||
});
|
});
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||||
@@ -4768,7 +4786,7 @@ describe("SelfHealingManager", () => {
|
|||||||
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
||||||
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||||
const reason = "task is marked 'failed': Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
const reason = "task is marked 'failed': Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, inReviewStallDeadlockThreshold: 3 });
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: true, inReviewStallDeadlockThreshold: 3 });
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||||
staleMergingTask({
|
staleMergingTask({
|
||||||
id: "FN-9999",
|
id: "FN-9999",
|
||||||
@@ -4790,7 +4808,7 @@ describe("SelfHealingManager", () => {
|
|||||||
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
vi.setSystemTime(new Date("2026-01-01T00:10:00.000Z"));
|
||||||
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||||
const reason = "task is marked 'failed': Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
const reason = "task is marked 'failed': Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, inReviewStallDeadlockThreshold: 0 });
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: true, inReviewStallDeadlockThreshold: 0 });
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||||
staleMergingTask({
|
staleMergingTask({
|
||||||
id: "FN-9999",
|
id: "FN-9999",
|
||||||
@@ -4817,7 +4835,7 @@ describe("SelfHealingManager", () => {
|
|||||||
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
const managerWithRecovery = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||||
const baseError = "Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
const baseError = "Failed to create worktree after 3 attempts: Branch fusion/fn-9999 conflict could not be auto-resolved";
|
||||||
const currentReason = `task is marked 'failed': ${baseError}`;
|
const currentReason = `task is marked 'failed': ${baseError}`;
|
||||||
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, inReviewStallDeadlockThreshold: 3 });
|
(store.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ taskStuckTimeoutMs: 60_000, autoMerge: true, inReviewStallDeadlockThreshold: 3 });
|
||||||
(store.listTasks as ReturnType<typeof vi.fn>)
|
(store.listTasks as ReturnType<typeof vi.fn>)
|
||||||
.mockResolvedValueOnce([
|
.mockResolvedValueOnce([
|
||||||
staleMergingTask({
|
staleMergingTask({
|
||||||
|
|||||||
Reference in New Issue
Block a user