Take a module's fingerprint from the indexer when its commit has no build, and never compose a module its want names into the node's own (issue 1945)
mesh/delivery merged: source.main moved to novox/mesh-controller@2bcd85d2df4c
mesh/check pass ac34bce49f58 on 2bcd85d2df4c | unit 966 run, 171 kept, 2 skipped | integration 1625 run, 232 kept, 7 skipped | over bound: integration…
mesh/delivery merged: source.main moved to novox/mesh-controller@2bcd85d2df4c
mesh/check pass ac34bce49f58 on 2bcd85d2df4c | unit 966 run, 171 kept, 2 skipped | integration 1625 run, 232 kept, 7 skipped | over bound: integration…
A catalogue merge that leaves a module's sources alone registers it at the new commit from the same done key, whose build record stands at its first commit, so the commit had no build and the module no fingerprint of the new form: it went into the node's own composition while its want named its own, and every node declared its files twice. currentFingerprints now reads the indexer's trunk value at the commit when no build points at it (1945/AC15), and a module a want or have names by its own composition is left out of the node's own (1945/AC16).
This commit is contained in:
@@ -218,7 +218,7 @@ func TestTheCompositionsOfANodeAreItsDeclaration(t *testing.T) {
|
||||
Resources []json.RawMessage `json:"resources"`
|
||||
}
|
||||
_ = json.Unmarshal(body, &d)
|
||||
comps, moved, err := compositionsOf(node, body, fps, nil, nil)
|
||||
comps, moved, _, err := compositionsOf(node, body, fps, nil, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", node, err)
|
||||
}
|
||||
@@ -253,7 +253,7 @@ func TestTheCompositionsOfANodeAreItsDeclaration(t *testing.T) {
|
||||
// unchanged it writes nothing; a changed input writes a new revision of that key alone, by compare-and-set.
|
||||
func TestACompositionIsWrittenOnceAndAgainOnlyWhenItChanges(t *testing.T) {
|
||||
body, fps := capturedBody(t, "g14")
|
||||
comps, _, err := compositionsOf("g14", body, fps, nil, nil)
|
||||
comps, _, _, err := compositionsOf("g14", body, fps, nil, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -342,7 +342,7 @@ func TestCompositionsOutsideTheFiveNewestAreDeleted(t *testing.T) {
|
||||
func TestAModuleWithNoResourceOfItsOwnStillHasItsComposition(t *testing.T) {
|
||||
body := []byte(`{"declaration":1,"resources":[]}`)
|
||||
fp := sdkdelivery.SourcePrefix2 + strings.Repeat("b", 64)
|
||||
comps, _, err := compositionsOf("laptop", body, map[string]string{"board": fp}, nil, []string{"board", "legacy"})
|
||||
comps, _, _, err := compositionsOf("laptop", body, map[string]string{"board": fp}, nil, []string{"board", "legacy"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -360,3 +360,54 @@ func TestAModuleWithNoResourceOfItsOwnStillHasItsComposition(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1945/AC16 (unit): a module the controller knows no fingerprint of the new form for, whose want or have on the node
|
||||
// names its own composition, is never in the node's own composition, neither its resources nor its filled paths, and is
|
||||
// named as left; a module neither names still goes with the node's own, its filled path with it. (Live from 2026-10-25
|
||||
// 12:43: zsh, power, restic and more were in both, and every node refused "2 resources declare X".)
|
||||
func TestAModuleItsWantNamesIsNeverInTheNodesOwnComposition(t *testing.T) {
|
||||
body := []byte(`{"declaration":1,"resources":[
|
||||
{"id":"zsh.rc","type":"file","module":"zsh","path":"/etc/zsh/zshrc"},
|
||||
{"id":"power.unit","type":"file","module":"power","path":"/etc/power.conf"},
|
||||
{"id":"mesh-wireguard.conf","type":"file","module":"mesh-wireguard","path":"/etc/wireguard/mesh0.conf"}],
|
||||
"filled_files":["/etc/zsh/zshrc","/etc/power.conf","/etc/wireguard/mesh0.conf"]}`)
|
||||
asked := map[string]int{}
|
||||
named := func(module string) (bool, error) {
|
||||
asked[module]++
|
||||
return module == "zsh" || module == "power", nil
|
||||
}
|
||||
comps, moved, left, err := compositionsOf("ace", body, map[string]string{}, nil, nil, named)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Join(left, ",") != "power,zsh" || strings.Join(moved, ",") != "mesh-wireguard" {
|
||||
t.Errorf("left %v, moved %v; want power,zsh left and mesh-wireguard moved", left, moved)
|
||||
}
|
||||
if asked["zsh"] != 1 || asked["power"] != 1 {
|
||||
t.Errorf("asked each module once: %v", asked)
|
||||
}
|
||||
own, _ := sdkdelivery.ComposedNodeKey("ace")
|
||||
for key, c := range comps {
|
||||
for _, id := range resourceIDs(t, c.Resources) {
|
||||
if strings.HasPrefix(id, "zsh.") || strings.HasPrefix(id, "power.") {
|
||||
t.Errorf("%s holds %s, which the module's own composition declares", key, id)
|
||||
}
|
||||
}
|
||||
for _, p := range c.Filled {
|
||||
if p == "/etc/zsh/zshrc" || p == "/etc/power.conf" {
|
||||
t.Errorf("%s names %s as filled, which the module's own composition names", key, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ids := strings.Join(resourceIDs(t, comps[own].Resources), " "); ids != "mesh-wireguard.conf" {
|
||||
t.Errorf("the node's own composition holds %q, want mesh-wireguard.conf alone", ids)
|
||||
}
|
||||
if f := strings.Join(comps[own].Filled, " "); f != "/etc/wireguard/mesh0.conf" {
|
||||
t.Errorf("the node's own composition names %q as filled, want mesh-wireguard's file alone", f)
|
||||
}
|
||||
|
||||
if _, _, _, err := compositionsOf("ace", body, map[string]string{}, nil, nil,
|
||||
func(string) (bool, error) { return false, fmt.Errorf("the wants bucket is gone") }); err == nil {
|
||||
t.Errorf("a want that cannot be read composed the node anyway")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user