feat: unify interactive operation coordination

This commit is contained in:
proxyctl coordinator
2026-07-17 22:23:31 +08:00
parent 177bf34354
commit 7c0b4481d7
17 changed files with 985 additions and 1013 deletions
+26 -20
View File
@@ -126,27 +126,31 @@ func TestActiveProfileSwitchCoordinatesEnabledTargetsWithoutRollback(t *testing.
}
inspectCallsBeforeSwitch := second.inspectCalls
var result app.Result
var failedCompletion app.Result
for update := range application.DispatchProgress(app.Intent{Kind: app.ActivateProfile, Name: "new"}) {
result = update
if len(update.Progress) == 1 && update.Progress[0].TargetID == "second" && !update.Progress[0].Applying {
var final app.OperationUpdate
var failedCompletion app.OperationUpdate
stream := application.StartOperation(app.Intent{Kind: app.ActivateProfile, Name: "new"})
for update := range stream.Updates {
final = update
progress := update.Progress()
if len(progress) == 1 && progress[0].TargetID == "second" && progress[0].Phase == app.TargetProgressFailed {
failedCompletion = update
}
}
if result.Snapshot.ActiveProfile != "new" {
t.Fatalf("Active Profile = %q", result.Snapshot.ActiveProfile)
if final.Snapshot.ActiveProfile != "new" {
t.Fatalf("Active Profile = %q", final.Snapshot.ActiveProfile)
}
if result.Err == nil || strings.Contains(result.Err.Error(), "secret") || !strings.Contains(result.Err.Error(), "second") {
t.Fatalf("redacted partial failure = %v", result.Err)
if final.Err() == nil || strings.Contains(final.Err().Error(), "secret") || !strings.Contains(final.Err().Error(), "second") {
t.Fatalf("redacted partial failure = %v", final.Err())
}
if got := result.Snapshot.Targets; got[0].State != target.Enabled || got[1].State != target.Drifted {
if got := final.Snapshot.Targets; got[0].State != target.Enabled || got[1].State != target.Drifted {
t.Fatalf("truthful partial states = %#v", got)
}
if len(result.Progress) != 2 || result.Progress[0].TargetID != "first" || result.Progress[0].State != target.Enabled || result.Progress[1].TargetID != "second" || result.Progress[1].State != target.Drifted || result.Progress[1].Evidence != "fresh actual configuration" {
t.Fatalf("per-Target progress = %#v", result.Progress)
progress := final.Progress()
if len(progress) != 2 || progress[0].TargetID != "first" || progress[0].State != target.Enabled || progress[1].TargetID != "second" || progress[1].State != target.Drifted || progress[1].Evidence != "fresh actual configuration" {
t.Fatalf("per-Target progress = %#v", progress)
}
if len(failedCompletion.Progress) != 1 || failedCompletion.Progress[0].State != target.Drifted || failedCompletion.Progress[0].Evidence != "fresh actual configuration" || failedCompletion.Err == nil {
failedProgress := failedCompletion.Progress()
if len(failedProgress) != 1 || failedProgress[0].State != target.Drifted || failedProgress[0].Evidence != "fresh actual configuration" || failedProgress[0].Err == nil {
t.Fatalf("failed completion event was not truthful: %#v", failedCompletion)
}
if failedCompletion.Snapshot.Targets[1].State != target.Drifted || failedCompletion.Snapshot.Targets[1].Evidence != "fresh actual configuration" {
@@ -155,8 +159,8 @@ func TestActiveProfileSwitchCoordinatesEnabledTargetsWithoutRollback(t *testing.
if second.inspectCalls < inspectCallsBeforeSwitch+2 {
t.Fatalf("failed SetDesired was not explicitly re-inspected: Inspect calls before=%d after=%d", inspectCallsBeforeSwitch, second.inspectCalls)
}
if !strings.Contains(result.Err.Error(), "fresh actual configuration") || !strings.Contains(result.Err.Error(), "Drifted") {
t.Fatalf("failure summary omitted fresh inspection: %v", result.Err)
if !strings.Contains(final.Err().Error(), "fresh actual configuration") || !strings.Contains(final.Err().Error(), "Drifted") {
t.Fatalf("failure summary omitted fresh inspection: %v", final.Err())
}
if len(first.applied) != 2 || first.applied[1] != "new" {
t.Fatalf("successful Target was not updated: %#v", first.applied)
@@ -231,7 +235,7 @@ func TestActiveProfileProgressReusesAvailabilityCache(t *testing.T) {
callsBeforeSwitch := adapter.availabilityCalls
var updates int
for range application.DispatchProgress(app.Intent{Kind: app.ActivateProfile, Name: "new"}) {
for range application.StartOperation(app.Intent{Kind: app.ActivateProfile, Name: "new"}).Updates {
updates++
}
if updates < 3 {
@@ -264,17 +268,19 @@ func TestActiveProfileSwitchStreamsApplyingAndCompletionForEachTarget(t *testing
t.Fatal(result.Err)
}
updates := application.DispatchProgress(app.Intent{Kind: app.ActivateProfile, Name: "new"})
updates := application.StartOperation(app.Intent{Kind: app.ActivateProfile, Name: "new"}).Updates
applying := <-updates
completed := <-updates
final := <-updates
if len(applying.Progress) != 1 || !applying.Progress[0].Applying || applying.Progress[0].TargetID != "shell" {
applyingProgress := applying.Progress()
if len(applyingProgress) != 1 || applyingProgress[0].Phase != app.TargetProgressRunning || applyingProgress[0].TargetID != "shell" {
t.Fatalf("applying update = %#v", applying)
}
if len(completed.Progress) != 1 || completed.Progress[0].Applying || completed.Progress[0].State != target.Enabled {
completedProgress := completed.Progress()
if len(completedProgress) != 1 || completedProgress[0].Phase != app.TargetProgressSucceeded || completedProgress[0].State != target.Enabled {
t.Fatalf("completion update = %#v", completed)
}
if !final.Complete || final.Snapshot.ActiveProfile != "new" {
if !final.IsSucceeded() || final.Snapshot.ActiveProfile != "new" {
t.Fatalf("final update = %#v", final)
}
}