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:
+82
-1
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user