The indexer writes each module's directory into modules.<m> and keeps it (issue 1606, ADR 0478 clause 8)

This commit is contained in:
2026-10-21 11:16:16 +02:00
parent 26de6bc625
commit 07a28b03c4
3 changed files with 36 additions and 5 deletions
@@ -215,8 +215,8 @@ func TestIndexerWritesModulesAtAMerge(t *testing.T) { // 1239/AC9
}
}
}
if m.FP != want || m.Repository != "novox/mesh-delivery" || m.Commit != merge {
t.Errorf("module = %+v within 5 s, want fp %s", m, want)
if m.FP != want || m.Repository != "novox/mesh-delivery" || m.Commit != merge || m.Path != "modules/a" { // 1606/AC2
t.Errorf("module = %+v within 5 s, want fp %s and path modules/a", m, want)
}
}
@@ -262,8 +262,8 @@ func TestIndexerKeepsManifestsAtAMerge(t *testing.T) { // 1444/AC4, 1449/AC4
}
digest := delivery.ManifestDigest(manifest)
if m.Manifest != digest || m.None2 != "toolchain not yet reported" || m.FP2 != "" || m.Inputs2 == nil || m.Inputs2.Tree != "newtree" ||
m.Inputs2.Locks["tools"] != goSum {
t.Errorf("module = %+v within 5 s, want its manifest digest %s, its inputs and none2 'toolchain not yet reported'", m, digest)
m.Inputs2.Locks["tools"] != goSum || m.Path != "modules/avahi" { // 1606/AC2
t.Errorf("module = %+v within 5 s, want its path modules/avahi, its manifest digest %s, its inputs and none2 'toolchain not yet reported'", m, digest)
}
kv, err := js.KeyValue(ctx, delivery.ManifestsBucket)
if err != nil {
@@ -63,7 +63,7 @@ func (ix *Indexer) applyMerged(ctx context.Context, f delivery.Forge) error {
continue
}
fp, none := fingerprintOf(k, f.Trees)
next := delivery.Module{Repository: f.Repository, Commit: f.Merge, FP: fp, None: none, Src: ix.srcOf(f.Repository, f.Merge), Manifest: digests[k.Path]}
next := delivery.Module{Repository: f.Repository, Commit: f.Merge, FP: fp, None: none, Src: ix.srcOf(f.Repository, f.Merge), Manifest: digests[k.Path], Path: k.Path}
// The new form (issue 1444, R4c-2): no module has a fingerprint of it yet, so each has the reason it has none, which
// names what is missing, from its manifest and lock hashes (inputs.go).
raw, has := f.Manifests[k.Path]
@@ -225,3 +225,34 @@ func TestARecordAsTheControllerWritesItGivesAFingerprint(t *testing.T) { // 1281
t.Errorf("module = %+v (%v), want a fingerprint, not none", m, ok)
}
}
func TestAMergeWritesTheModulesDirectoryAndKeepsItThroughSourceAndRecompute(t *testing.T) { // 1606/AC1, AC2
ix, mods := modulesIndexer(t,
rec(t, "build-1", "a", "novox/mesh-delivery", "modules/a", "main", "", "2026-10-19T09:00:00Z", aInputs),
rec(t, "build-2", "r", "novox/mesh-delivery", "", "main", "", "2026-10-19T09:00:00Z", strings.Replace(aInputs, `"Module":"a"`, `"Module":"r"`, 1)))
ctx := context.Background()
if err := ix.Apply(ctx, mergedMsg("novox/mesh-delivery", map[string]string{"modules/a": "newtree", "": "roottree"})); err != nil {
t.Fatal(err)
}
for module, want := range map[string]string{"a": "modules/a", "r": ""} {
if m, ok := moduleOf(t, mods, module); !ok || m.Path != want {
t.Errorf("after the merge %s = %+v (%v), want path %q", module, m, ok, want)
}
}
if err := ix.ApplySource(ctx, 7, sourceOf("novox/mesh-delivery", merge)); err != nil {
t.Fatal(err)
}
if err := ix.Recompute(ctx); err != nil {
t.Fatal(err)
}
if m, _ := moduleOf(t, mods, "a"); m.Path != "modules/a" || m.Src != 7 {
t.Errorf("after the source and a recompute a = %+v, want path modules/a kept and Src 7", m)
}
raw := string(mods.vals["a"])
if !strings.Contains(raw, `"path":"modules/a"`) {
t.Errorf("the stored value %s has no path", raw)
}
if strings.Contains(string(mods.vals["r"]), `"path"`) {
t.Errorf("the root module's value %s names a path", mods.vals["r"])
}
}