DLV-I17, I18: the indexer's whole-module test keeps a contracts module's definitions, a pull request's unparsed one, and drops it on close

Research 081 test 21 as a case of the indexer's existing whole-module test (no new test function:
mesh-delivery is over its test budget).

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 14:20:01 +01:00
parent aa647d0eda
commit 598204b4c4
@@ -5,6 +5,7 @@ package main
import (
"context"
"encoding/json"
"errors"
"os"
"strings"
"testing"
@@ -15,6 +16,8 @@ import (
"git.novox.be/novox/mesh-sdk/go/buscompose"
"git.novox.be/novox/mesh-sdk/go/delivery"
"mesh-delivery-indexer/internal/index"
)
// TestAMeshSDKMergeMovesOnlyTheModulesImportingAChangedPackage (ADR 0593 §2-§4; D11): the indexer whole against the
@@ -48,7 +51,7 @@ func TestAMeshSDKMergeMovesOnlyTheModulesImportingAChangedPackage(t *testing.T)
m1: {"go.mod": "f1", "go.sum": "f2", "stdio.go": "f3", "announce/announce.go": "f4", "buildstep/step.go": "f5"},
m2: {"go.mod": "f1", "go.sum": "f2", "stdio.go": "f3", "announce/announce.go": "f4", "buildstep/step.go": "f6"},
}
var packages jetstream.KeyValue
var packages, seatDefs jetstream.KeyValue
js, ctx, _, modules := startIndexer(t, func(context.Context, buildLog) {}, func(ctx context.Context, js jetstream.JetStream) {
var err error
if packages, err = js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: delivery.PackagesBucket, History: delivery.PackagesHistory}); err != nil {
@@ -70,6 +73,14 @@ func TestAMeshSDKMergeMovesOnlyTheModulesImportingAChangedPackage(t *testing.T)
}
}
serveForge(t, js.Conn(), listing, goSumContent)
// The seat definitions' state and stream (DLV-I17), as the grants part makes them from the manifest.
if seatDefs, err = js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: index.SeatDefinitionsBucket, History: 5}); err != nil {
t.Fatal(err)
}
if _, err := js.CreateStream(ctx, jetstream.StreamConfig{Name: "INDEXER_SEAT_DEFINITIONS",
Subjects: []string{"mesh.stream.mesh-delivery-indexer.event." + index.SeatDefinitionChangedEvent}}); err != nil {
t.Fatal(err)
}
})
merged := func(repo string, number int, merge string, f delivery.Forge) {
t.Helper()
@@ -179,8 +190,67 @@ func TestAMeshSDKMergeMovesOnlyTheModulesImportingAChangedPackage(t *testing.T)
if now := module("plain", func(delivery.Module) bool { return true }); now.FP2 != plain.FP2 {
t.Errorf("plain moved from %s to %s, though it imports nothing the merge changed", plain.FP2, now.FP2)
}
// DLV-I17, I18 (research 081 test 21, design 26): mesh-contracts merges a valid definition, said once; a pull
// request's head whose definition does not parse is kept as its entry naming why while the trunk's stays; it closes
// and its entry goes.
const contractsMerge, badHead = "5555555555555555555555555555555555555555", "6666666666666666666666666666666666666666"
git := `{"format":1,"seat":"git","scope":"mesh","grain":"seat-list","decision":"novox/hq ADR 0111","delivers":"git"}`
seatFiles[contractsMerge] = map[string]string{"seats/index.json": `{"format":1,"seats":["git"]}`, "seats/git/seat.json": git}
seatFiles[badHead] = map[string]string{"seats/index.json": `{"format":1,"seats":["git"]}`, "seats/git/seat.json": `{"format":1,"seat":"git"}`}
contracts := `{"module":"mesh-contracts","version":"1","build":{"artifacts":[{"name":"go","kind":"package","language":"go","paths":["go"],"series":"0.1","generated-from":"."}]}}`
merged("novox/mesh-contracts", 80, contractsMerge, delivery.Forge{Root: "dddddddddddddddddddddddddddddddddddddddd",
Trees: map[string]string{"": "dddddddddddddddddddddddddddddddddddddddd"}, Manifests: map[string]string{"": contracts}})
entry := func(key string, ok func(index.SeatDefinitionEntry) bool) index.SeatDefinitionEntry {
t.Helper()
var e index.SeatDefinitionEntry
for deadline := time.Now().Add(20 * time.Second); time.Now().Before(deadline); time.Sleep(50 * time.Millisecond) {
if v, err := seatDefs.Get(ctx, key); err == nil && json.Unmarshal(v.Value(), &e) == nil && ok(e) {
return e
}
}
t.Fatalf("%s.%s = %+v within 20 s", index.SeatDefinitionsState, key, e)
return e
}
trunk := entry("git.trunk", func(e index.SeatDefinitionEntry) bool { return e.Commit == contractsMerge && e.Digest != "" })
pull := func(action string) {
t.Helper()
data, _ := delivery.EncodeForge(delivery.Forge{Kind: delivery.ForgePull, Action: action, Repository: "novox/mesh-contracts", Branch: "feat/y",
Number: 81, Head: badHead, Dirs: []string{""}, DirsKnown: true, Manifests: map[string]string{"": contracts}})
if _, err := js.Publish(ctx, "mesh.stream.mesh-delivery-forge-bridge.event.forge.novox.mesh-contracts.pull", data); err != nil {
t.Fatal(err)
}
}
pull(delivery.PullUpdated)
pk := index.SeatDefinitionKey("git", index.SourcePull, "novox/mesh-contracts", 81)
if bad := entry(pk, func(e index.SeatDefinitionEntry) bool { return e.Unparsed != "" }); !strings.Contains(bad.Unparsed, "scope") || bad.Definition != nil {
t.Errorf("the pull request's entry %+v, want why it does not parse and no definition", bad)
}
if now := entry("git.trunk", func(index.SeatDefinitionEntry) bool { return true }); now.Digest != trunk.Digest {
t.Errorf("the trunk's entry moved to %+v on a pull request's head", now)
}
pull(delivery.PullClosed)
for deadline := time.Now().Add(20 * time.Second); ; time.Sleep(50 * time.Millisecond) {
if _, err := seatDefs.Get(ctx, pk); errors.Is(err, jetstream.ErrKeyNotFound) {
break
}
if time.Now().After(deadline) {
t.Fatalf("%s is kept 20 s after its pull request closed", pk)
}
}
info, err := js.Stream(ctx, "INDEXER_SEAT_DEFINITIONS")
if err != nil {
t.Fatal(err)
}
// Said: the trunk's git, and the closed pull request's removal; the unparsed head says nothing.
if n := info.CachedInfo().State.Msgs; n != 2 {
t.Errorf("seat-definition-changed said %d times, want 2", n)
}
}
// seatFiles are mesh-contracts' files by commit, as gitea_get_file answers them.
var seatFiles = map[string]map[string]string{}
// serveForge answers the forge's tools on the bus as the gitea module does: gitea_commit_trees (the trees of a commit,
// or with files the blobs under each directory of mesh-sdk's listing at that commit), gitea_get_file (every go.sum
// holds goSum) and gitea_contains.
@@ -213,6 +283,17 @@ func serveForge(t *testing.T, nc *nats.Conn, listing map[string]map[string]strin
t.Fatal(err)
}
file, err := nc.Subscribe("mesh.mod.gitea.tool.gitea_get_file", func(m *nats.Msg) {
var a struct{ Repo, Path, Ref string }
_ = json.Unmarshal(m.Data, &a)
if a.Repo == "mesh-contracts" { // the seat definitions (DLV-I17): a path the commit does not hold is a 404
if v, ok := seatFiles[a.Ref][a.Path]; ok {
reply(m, map[string]any{"file": map[string]any{"content": v}})
} else {
raw, _ := json.Marshal(map[string]any{"error": "gitea: 404 Not Found", "node": "n0"})
_ = m.Respond(raw)
}
return
}
reply(m, map[string]any{"file": map[string]any{"content": goSum}})
})
if err != nil {