diff --git a/modules/mesh-delivery-indexer/judge/judge.go b/modules/mesh-delivery-indexer/judge/judge.go index 9ebb2101..32ae12ca 100644 --- a/modules/mesh-delivery-indexer/judge/judge.go +++ b/modules/mesh-delivery-indexer/judge/judge.go @@ -189,6 +189,7 @@ const Unnamed = "(between manifests)" func Request(r composer.Request) (composer.Verdict, error) { v := composer.Verdict{V: composer.Version, SDK: Identity()} seen := map[string]bool{} + counts := trunkOldSections(r) for _, c := range r.Cases { if seen[c.Name] { return composer.Verdict{}, fmt.Errorf("the case %q is named twice", c.Name) @@ -201,7 +202,7 @@ func Request(r composer.Request) (composer.Verdict, error) { } raws[name] = m.Raw } - refused, unnamed := Shelf(raws, r.Predefined, 0) + refused, unnamed := ShelfCounting(raws, r.Predefined, 0, counts) cv := composer.CaseVerdict{Name: c.Name, Manifests: map[string]composer.ManifestRead{}} for name := range raws { if problems := refused[name]; len(problems) > 0 { @@ -218,6 +219,39 @@ func Request(r composer.Request) (composer.Verdict, error) { return v, nil } +// TrunkCase is the case of a request holding the catalogue as the trunk holds it (the checker's JudgeTrunk). +const TrunkCase = "trunk" + +// trunkOldSections counts the old sections the modules accepted at the trunk use, as the indexer counts them from its +// verdicts (issue 1966 D4, ADR 0595 ยง11): a change is refused at the merge check exactly as at take-in (judged once, ADR +// 0578). Nil where the request holds no trunk case, which refuses no use of a section. +func trunkOldSections(r composer.Request) OldSectionCounts { + for _, c := range r.Cases { + if c.Name != TrunkCase { + continue + } + raws := map[string][]byte{} + for name, m := range c.Manifests { + if len(m.Raw) > 0 { + raws[name] = m.Raw + } + } + refused, _ := Shelf(raws, r.Predefined, 0) + var accepted []catalogue.Manifest + for name, raw := range raws { + if len(refused[name]) > 0 { + continue + } + if m, err := catalogue.Decode(raw); err == nil { + m.Module = name + accepted = append(accepted, m) + } + } + return CountOldSections(accepted) + } + return nil +} + var ( identityOnce sync.Once identity string diff --git a/modules/mesh-delivery-indexer/judge/judge_test.go b/modules/mesh-delivery-indexer/judge/judge_test.go index 8243b338..406be32e 100644 --- a/modules/mesh-delivery-indexer/judge/judge_test.go +++ b/modules/mesh-delivery-indexer/judge/judge_test.go @@ -86,6 +86,27 @@ func TestTheJudge(t *testing.T) { v.Cases[0].Manifests["b"].Accepted || !strings.Contains(v.Cases[0].Manifests["b"].Refused, `requires "amqp"`) { t.Fatalf("request: %+v %v", v, err) } + // 1966/AC11: the checker's judge counts the old sections from the trunk case as the indexer does from its verdicts (the + // foundation left out): a change adding logs where no trunk module uses them is refused, the foundation's accepted, and + // state, which a trunk module uses, is accepted. + old := composer.Request{V: composer.Version, Cases: []composer.Case{ + {Name: "change", Manifests: map[string]composer.Manifest{ + "user": {Raw: json.RawMessage(`{"module":"user","version":"1","state":["x"]}`)}, + "late": {Raw: json.RawMessage(`{"module":"late","version":"1","logs":[{"name":"l"}]}`)}, + "newer": {Raw: json.RawMessage(`{"module":"newer","version":"1","state":["y"]}`)}, + "mesh-grants": {Raw: json.RawMessage(`{"module":"mesh-grants","version":"1","logs":[{"name":"l"}]}`)}}}, + {Name: "trunk", Manifests: map[string]composer.Manifest{ + "user": {Raw: json.RawMessage(`{"module":"user","version":"1","state":["x"]}`)}, + "mesh-grants": {Raw: json.RawMessage(`{"module":"mesh-grants","version":"1","logs":[{"name":"l"}]}`)}}}}} + ov, err := Request(old) + if err != nil { + t.Fatal(err) + } + got := ov.Cases[0].Manifests + if got["late"].Accepted || !strings.Contains(got["late"].Refused, "late uses the old section logs") || + !got["newer"].Accepted || !got["user"].Accepted || !got["mesh-grants"].Accepted { + t.Errorf("the change's old sections: %+v", got) + } r.Cases[0].Manifests["c"] = composer.Manifest{Digest: strings.Repeat("a", 64)} if _, err := Request(r); err == nil { t.Fatal("a manifest left as a digest was judged")