The indexer's whole-module test proves a merge kept as one catalog graph revision, said on the seat, and the recompute and the drop answered by the running indexer (milestone 47/G W4.13)
Rows in TestIndexerWritesModulesAtAMerge; the pin rows come with W4.5. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -686,8 +686,14 @@ func (l buildLog) end(t *testing.T, repo, module, path string) {
|
||||
// message on FORGE makes modules.<m> within 20 s, the fingerprint of the merge's tree and the recorded inputs.
|
||||
func TestIndexerWritesModulesAtAMerge(t *testing.T) { // 1239/AC9; I1, I3: the modules are the merged message's, no build record names them (issue 1851)
|
||||
// The bucket holds only build-agent's record, which no fingerprint reads since R4g (ADR 0530 §1).
|
||||
var asks jetstream.KeyValue
|
||||
js, ctx, _, modules := startIndexer(t, func(ctx context.Context, builds buildLog) {
|
||||
builds.end(t, "novox/mesh-controller", "build-agent", "modules/build-agent")
|
||||
}, func(ctx context.Context, js jetstream.JetStream) {
|
||||
var err error
|
||||
if asks, err = js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: index.TakeInsBucket, History: 1}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
const merge = "89abcdef0123456789abcdef0123456789abcdef"
|
||||
data, err := forgemsg.EncodeForge(forgemsg.Forge{Kind: forgemsg.ForgeMerged, Repository: "novox/mesh-delivery", Branch: "feat/x", Number: 12,
|
||||
@@ -710,6 +716,60 @@ func TestIndexerWritesModulesAtAMerge(t *testing.T) { // 1239/AC9; I1, I3: the m
|
||||
if m.Repository != "novox/mesh-delivery" || m.Commit != merge || m.Path != "modules/a" || m.Manifest == "" || m.Fp != "" || m.None != "" { // 1606/AC2
|
||||
t.Errorf("module = %+v within 20 s, want path modules/a, its manifest, and no value of today's form", m)
|
||||
}
|
||||
// Milestone 47/G W4.13 (design 47, the indexer whole): the source revision taken in is one catalog graph revision kept
|
||||
// as objects, said as catalog-revision on the seat's subject, every entry it lists stored once by digest.
|
||||
objects := newBusObjects(js, testAccount, index.CatalogRevisionsObjects)
|
||||
list, err := index.ListRevisions(ctx, objects, false)
|
||||
if err != nil || len(list.Revisions) != 1 || list.Revisions[0].Name != "trunk.1" || !list.Revisions[0].Current ||
|
||||
list.Entries != list.Revisions[0].Entries || len(list.Unlisted) != 0 || list.Fill.Bytes == 0 {
|
||||
t.Fatalf("revisions kept = %+v (%v): want trunk.1 alone, current, each entry it lists stored once", list, err)
|
||||
}
|
||||
events, err := js.Stream(ctx, "EVENTS")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if msg, err := events.GetLastMsgForSubject(ctx, "mesh.seat.mesh-catalog.event."+meshcatalog.EventCatalogRevision); err != nil ||
|
||||
!strings.Contains(string(msg.Data), `"revision":1`) {
|
||||
t.Errorf("catalog-revision said: %v (%v): want revision 1", msg, err)
|
||||
}
|
||||
// W4.12 through the process: a recompute by hand moves nothing and answers equal; a candidate's half dropped by hand
|
||||
// leaves the trunk's revision and its entries.
|
||||
if err := index.KeepRevision(ctx, objects, meshcatalog.CatalogRevision{Kind: "candidate", Group: "g1", Heads: "h1", Revision: 1,
|
||||
Entries: []meshcatalog.EntryRef{{Module: "x", Digest: "dx"}}}, map[string][]byte{"dx": []byte(`{"module":"x"}`)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
answer := func(key string, value []byte) index.TakenIn {
|
||||
t.Helper()
|
||||
w, err := asks.Watch(ctx, key, jetstream.UpdatesOnly())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer w.Stop()
|
||||
if _, err := asks.Put(ctx, key, value); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for e := range w.Updates() {
|
||||
if e == nil {
|
||||
continue
|
||||
}
|
||||
if a, err := index.DecodeTakeIn(e.Value()); err == nil && a.Done() {
|
||||
return *a.Result
|
||||
}
|
||||
}
|
||||
t.Fatalf("%s is not answered", key)
|
||||
return index.TakenIn{}
|
||||
}
|
||||
key, value, _ := index.NewRecomputeAsk("a check", "ctl", time.Now())
|
||||
if r := answer(key, value); !r.Stored || !strings.Contains(r.Answer, "equal to the kept revision 1") {
|
||||
t.Errorf("indexer_recompute answered %+v: want equal to the kept revision 1", r)
|
||||
}
|
||||
key, value, _ = index.NewDropCandidateGraphAsk("g1", "h1", "its gate event never came", "ctl", time.Now())
|
||||
if r := answer(key, value); !r.Stored || !slices.Equal(r.Dropped, []string{"entry.dx"}) {
|
||||
t.Errorf("indexer_drop_candidate_graph answered %+v: want candidate.g1.h1 dropped with entry.dx", r)
|
||||
}
|
||||
if after, err := index.ListRevisions(ctx, objects, false); err != nil || len(after.Revisions) != 1 || after.Entries != list.Entries {
|
||||
t.Errorf("revisions after the drop = %+v (%v): want trunk.1 and its entries alone", after, err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestIndexerKeepsManifestsAtAMerge: a merged message of mesh-catalog carrying the real manifest of the module avahi and the
|
||||
|
||||
Reference in New Issue
Block a user