fix: make target progress reflect fresh state

This commit is contained in:
proxyctl coordinator
2026-07-17 09:21:36 +08:00
parent fd113fb316
commit fb456f35e4
6 changed files with 198 additions and 40 deletions
+68 -9
View File
@@ -16,11 +16,13 @@ import (
)
type coordinatedTarget struct {
id string
state target.State
applied []string
appliedName string
failName string
id string
state target.State
applied []string
appliedName string
failName string
availabilityCalls int
inspectCalls int
}
func (t *coordinatedTarget) ID() string { return t.id }
@@ -28,13 +30,15 @@ func (t *coordinatedTarget) Description() target.Description {
return target.Description{Name: t.id, Summary: "summary", Details: "effects, non-effects, ownership, permissions, and side effects"}
}
func (t *coordinatedTarget) Availability(context.Context) target.Availability {
t.availabilityCalls++
return target.Availability{Available: true, Evidence: "detected"}
}
func (t *coordinatedTarget) Inspect(_ context.Context, active *profile.Profile) target.Inspection {
t.inspectCalls++
if t.state == target.Enabled && (active == nil || (t.appliedName != "" && active.Name != t.appliedName)) {
return target.Inspection{State: target.Drifted, Evidence: "managed configuration does not match the Active Profile"}
}
return target.Inspection{State: t.state, Evidence: "actual configuration"}
return target.Inspection{State: t.state, Evidence: "fresh actual configuration"}
}
func (t *coordinatedTarget) Confirmation(bool) string { return "" }
func (t *coordinatedTarget) SetDesired(_ context.Context, enabled bool, active *profile.Profile) target.OperationResult {
@@ -45,7 +49,7 @@ func (t *coordinatedTarget) SetDesired(_ context.Context, enabled bool, active *
t.applied = append(t.applied, active.Name)
if active.Name == t.failName {
t.state = target.Drifted
return target.OperationResult{Inspection: target.Inspection{State: t.state, Evidence: "re-inspected partial write"}, Err: errors.New("failed using http://alice:secret@proxy.example")}
return target.OperationResult{Inspection: target.Inspection{State: target.Enabled, Evidence: "stale operation state"}, Err: errors.New("failed using http://alice:secret@proxy.example")}
}
t.state = target.Enabled
t.appliedName = active.Name
@@ -74,7 +78,15 @@ func TestActiveProfileSwitchCoordinatesEnabledTargetsWithoutRollback(t *testing.
}
}
result := application.Dispatch(app.Intent{Kind: app.ActivateProfile, Name: "new"})
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 {
failedCompletion = update
}
}
if result.Snapshot.ActiveProfile != "new" {
t.Fatalf("Active Profile = %q", result.Snapshot.ActiveProfile)
}
@@ -84,9 +96,21 @@ func TestActiveProfileSwitchCoordinatesEnabledTargetsWithoutRollback(t *testing.
if got := result.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 {
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)
}
if len(failedCompletion.Progress) != 1 || failedCompletion.Progress[0].State != target.Drifted || failedCompletion.Progress[0].Evidence != "fresh actual configuration" || failedCompletion.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" {
t.Fatalf("failed completion snapshot was not truthful: %#v", failedCompletion.Snapshot.Targets[1])
}
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 len(first.applied) != 2 || first.applied[1] != "new" {
t.Fatalf("successful Target was not updated: %#v", first.applied)
}
@@ -140,6 +164,41 @@ func TestApplicationCoordinatesMultipleRealAndFakeHermeticAdaptersThroughPartial
}
}
func TestActiveProfileProgressReusesAvailabilityCache(t *testing.T) {
adapter := &coordinatedTarget{id: "shell", state: target.Disabled}
application, err := app.NewWithTargets(profile.NewFileStore(filepath.Join(t.TempDir(), "profiles.json")), []target.Target{adapter})
if err != nil {
t.Fatal(err)
}
for _, name := range []string{"old", "new"} {
if result := application.Dispatch(app.Intent{Kind: app.CreateProfile, Profile: profile.Profile{Name: name, SingleURL: "http://proxy.example:8080"}}); result.Err != nil {
t.Fatal(result.Err)
}
}
if result := application.Dispatch(app.Intent{Kind: app.ActivateProfile, Name: "old"}); result.Err != nil {
t.Fatal(result.Err)
}
if result := application.Dispatch(app.Intent{Kind: app.SetTargetDesired, TargetID: "shell", Enabled: true}); result.Err != nil {
t.Fatal(result.Err)
}
callsBeforeSwitch := adapter.availabilityCalls
var updates int
for range application.DispatchProgress(app.Intent{Kind: app.ActivateProfile, Name: "new"}) {
updates++
}
if updates < 3 {
t.Fatalf("progress updates = %d", updates)
}
if adapter.availabilityCalls != callsBeforeSwitch {
t.Fatalf("availability probes during progress = %d, want cached count %d", adapter.availabilityCalls, callsBeforeSwitch)
}
application.Dispatch(app.Intent{Kind: app.RefreshTargets})
if adapter.availabilityCalls != callsBeforeSwitch+1 {
t.Fatalf("explicit refresh probe count = %d, want %d", adapter.availabilityCalls, callsBeforeSwitch+1)
}
}
func TestActiveProfileSwitchStreamsApplyingAndCompletionForEachTarget(t *testing.T) {
adapter := &coordinatedTarget{id: "shell", state: target.Disabled}
application, err := app.NewWithTargets(profile.NewFileStore(filepath.Join(t.TempDir(), "profiles.json")), []target.Target{adapter})