Find a want's have by the have's own key: want.<node>.<module> against <node>.<module> (release 6, issue 1945)

This commit is contained in:
2026-10-24 18:43:22 +02:00
parent af6bcea41e
commit aa7e53112b
2 changed files with 23 additions and 11 deletions
+7 -3
View File
@@ -20,14 +20,18 @@ import (
func currentNodes(wants map[string]sdkdelivery.Want, haves map[string]sdkdelivery.Have) map[string]bool {
out := map[string]bool{}
for key, w := range wants {
node, _, err := sdkdelivery.ParseWantKey(key)
node, module, err := sdkdelivery.ParseWantKey(key)
if err != nil {
continue // the node's own want: its composition is the node-engine's own
continue // the node's own want, or a fingerprint the assigner holds: not a module's want
}
if _, seen := out[node]; !seen {
out[node] = true
}
h, had := haves[key]
haveKey, err := sdkdelivery.HaveKey(node, module) // `<node>.<module>`, where a want's key is `want.<node>.<module>`
if err != nil {
continue
}
h, had := haves[haveKey]
switch {
case w.Removed:
if had && h.Phase != sdkdelivery.PhaseRemoved {
+16 -8
View File
@@ -20,6 +20,7 @@ func TestAMachineIsCurrentWhenItHasWhatIsWantedOfIt(t *testing.T) {
have := func(f, composed string, phase sdkdelivery.Phase) sdkdelivery.Have {
return sdkdelivery.Have{V: 1, FP: f, Composed: composed, Phase: phase, Health: sdkdelivery.HealthOK}
}
// A want's key is `want.<node>.<module>` and a have's is `<node>.<module>`: the same module, two buckets.
key := func(node, module string) string {
k, err := sdkdelivery.WantKey(node, module)
if err != nil {
@@ -27,6 +28,13 @@ func TestAMachineIsCurrentWhenItHasWhatIsWantedOfIt(t *testing.T) {
}
return k
}
hkey := func(node, module string) string {
k, err := sdkdelivery.HaveKey(node, module)
if err != nil {
t.Fatal(err)
}
return k
}
for _, c := range []struct {
what string
wants map[string]sdkdelivery.Want
@@ -35,38 +43,38 @@ func TestAMachineIsCurrentWhenItHasWhatIsWantedOfIt(t *testing.T) {
}{
{"everything had as wanted",
map[string]sdkdelivery.Want{key("anchor", "web"): want(fp("a"), "d1")},
map[string]sdkdelivery.Have{key("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]bool{"anchor": true}},
{"a module not had yet",
map[string]sdkdelivery.Want{key("anchor", "web"): want(fp("a"), "d1")},
nil, map[string]bool{"anchor": false}},
{"an older fingerprint",
map[string]sdkdelivery.Want{key("anchor", "web"): want(fp("b"), "d1")},
map[string]sdkdelivery.Have{key("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]bool{"anchor": false}},
{"the same fingerprint, an older composition",
map[string]sdkdelivery.Want{key("anchor", "web"): want(fp("a"), "d2")},
map[string]sdkdelivery.Have{key("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]bool{"anchor": false}},
{"still applying",
map[string]sdkdelivery.Want{key("anchor", "web"): want(fp("a"), "d1")},
map[string]sdkdelivery.Have{key("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseApplying)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseApplying)},
map[string]bool{"anchor": false}},
{"held for a backup that failed",
map[string]sdkdelivery.Want{key("anchor", "web"): want(fp("a"), "d1")},
map[string]sdkdelivery.Have{key("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseHeld)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseHeld)},
map[string]bool{"anchor": false}},
{"a module wanted removed that is gone",
map[string]sdkdelivery.Want{key("anchor", "web"): {V: 1, Removed: true}},
map[string]sdkdelivery.Have{key("anchor", "web"): have("", "", sdkdelivery.PhaseRemoved)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have("", "", sdkdelivery.PhaseRemoved)},
map[string]bool{"anchor": true}},
{"a module wanted removed that still runs",
map[string]sdkdelivery.Want{key("anchor", "web"): {V: 1, Removed: true}},
map[string]sdkdelivery.Have{key("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]bool{"anchor": false}},
{"one machine behind does not hold another back",
map[string]sdkdelivery.Want{key("anchor", "web"): want(fp("a"), "d1"), key("laptop", "web"): want(fp("a"), "d1")},
map[string]sdkdelivery.Have{key("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]sdkdelivery.Have{hkey("anchor", "web"): have(fp("a"), "d1", sdkdelivery.PhaseRunning)},
map[string]bool{"anchor": true, "laptop": false}},
} {
got := currentNodes(c.wants, c.haves)