feat: backend executor implement
This commit is contained in:
@@ -72,6 +72,56 @@ func TestCoordinatorLeavesIntentPendingWhenInspectionIsUnknown(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoordinatorRetriesFailedStepOnlyAfterManualResumeInspection(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
store := openTestStore(t)
|
||||
record := createTestTransaction(t, store, "retry-failed")
|
||||
intent := StepIntent{Key: "restore-gateway", Name: "restore gateway", Intent: json.RawMessage(`{}`)}
|
||||
operation := &fakeOperation{applyErr: errors.New("gateway executable unavailable"), result: json.RawMessage(`{"restored":true}`)}
|
||||
coordinator := newTestCoordinator(t, store)
|
||||
|
||||
failed, err := coordinator.ExecuteStep(ctx, record.ID, intent, operation)
|
||||
if err == nil || failed.Status != StepFailed {
|
||||
t.Fatalf("unexpected initial failed step: step=%+v err=%v", failed, err)
|
||||
}
|
||||
if operation.applyCalls.Load() != 1 || operation.inspectCalls.Load() != 1 {
|
||||
t.Fatalf("initial call retried unexpectedly: apply=%d inspect=%d", operation.applyCalls.Load(), operation.inspectCalls.Load())
|
||||
}
|
||||
|
||||
operation.applyErr = nil
|
||||
recovered, err := coordinator.ExecuteStep(ctx, record.ID, intent, operation)
|
||||
if err != nil || recovered.Status != StepSucceeded {
|
||||
t.Fatalf("recover failed step: step=%+v err=%v", recovered, err)
|
||||
}
|
||||
if operation.applyCalls.Load() != 2 || operation.inspectCalls.Load() != 3 {
|
||||
t.Fatalf("unexpected manual recovery calls: apply=%d inspect=%d", operation.applyCalls.Load(), operation.inspectCalls.Load())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoordinatorCompletesFailedStepAlreadyAppliedBeforeManualResume(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
store := openTestStore(t)
|
||||
record := createTestTransaction(t, store, "recover-failed-applied")
|
||||
intent := StepIntent{Key: "restore-gateway", Name: "restore gateway", Intent: json.RawMessage(`{}`)}
|
||||
operation := &fakeOperation{applyErr: errors.New("gateway reload result unavailable"), result: json.RawMessage(`{"restored":true}`)}
|
||||
coordinator := newTestCoordinator(t, store)
|
||||
|
||||
if _, err := coordinator.ExecuteStep(ctx, record.ID, intent, operation); err == nil {
|
||||
t.Fatal("expected initial external step failure")
|
||||
}
|
||||
operation.applyErr = nil
|
||||
operation.applied = true
|
||||
recovered, err := coordinator.ExecuteStep(ctx, record.ID, intent, operation)
|
||||
if err != nil || recovered.Status != StepSucceeded {
|
||||
t.Fatalf("complete externally applied failed step: step=%+v err=%v", recovered, err)
|
||||
}
|
||||
if operation.applyCalls.Load() != 1 || operation.inspectCalls.Load() != 2 {
|
||||
t.Fatalf("externally applied step was repeated: apply=%d inspect=%d", operation.applyCalls.Load(), operation.inspectCalls.Load())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoordinatorExclusiveExecutionHonorsContext(t *testing.T) {
|
||||
t.Parallel()
|
||||
store := openTestStore(t)
|
||||
|
||||
Reference in New Issue
Block a user