diff --git a/internal/broker/agreement_catalogue_test.go b/internal/broker/agreement_catalogue_test.go index 05c2c028..96eba076 100644 --- a/internal/broker/agreement_catalogue_test.go +++ b/internal/broker/agreement_catalogue_test.go @@ -105,7 +105,11 @@ func theCataloguesEvents(t *testing.T) ([]AnEmitter, []AConsumer, []DeclaredSeat emitters = append(emitters, *emitter) } if consumer != nil { - consumers = append(consumers, *consumer) + kept, setAside := setAsideRetiredSeats(*consumer) + for _, note := range setAside { + t.Log(note) + } + consumers = append(consumers, kept) } seats = append(seats, declared...) } @@ -115,6 +119,53 @@ func theCataloguesEvents(t *testing.T) ([]AnEmitter, []AConsumer, []DeclaredSeat return emitters, consumers, seats } +// setAsideRetiredSeats takes out of a consumer the events of a seat the mesh has retired, and says each one. +// The check judges against the catalogue's trunk (ADR 0484 clause 4), and a group that retires a seat while +// its catalogue pull request drops the consume (ADR 0524 section 5) meets the trunk still holding it: against +// that catalogue the seat is gone and the subscription falls back to a module subject nobody owns. It is set +// aside and logged, never silently dropped; an unknown seat that is not retired is still judged. +func setAsideRetiredSeats(c AConsumer) (AConsumer, []string) { + kept := AConsumer{Module: c.Module} + var notes []string + for _, want := range c.Consumes { + seat, event, named := strings.Cut(want, ".") + if replacement, retired := catalogue.RetiredSeats[seat]; named && retired { + notes = append(notes, c.Module+" still consumes "+seat+"."+event+"; the seat is retired (its work is "+ + replacement+"); the catalogue drops it in the same change (ADR 0524 ยง5), and the check judges against the catalogue's trunk (ADR 0484 clause 4)") + continue + } + kept.Consumes = append(kept.Consumes, want) + } + return kept, notes +} + +func TestARetiredSeatsConsumeIsSetAsideAndAnUnknownOneIsNot(t *testing.T) { + var retired string + for name := range catalogue.RetiredSeats { + retired = name + break + } + if retired == "" { + t.Skip("no seat is retired") + } + kept, notes := setAsideRetiredSeats(AConsumer{Module: "m", + Consumes: []string{retired + ".built", "no-such-seat.built", "plain"}}) + if len(notes) != 1 || !strings.Contains(notes[0], retired+".built") { + t.Fatalf("the retired seat's consume was not set aside and said: %v", notes) + } + if strings.Join(kept.Consumes, ",") != "no-such-seat.built,plain" { + t.Fatalf("what stays to be judged is wrong: %v", kept.Consumes) + } + if bad := Disagreements([]AnEmitter{{Module: "other", Emits: []string{"x"}}}, + []AConsumer{kept}, nil); len(bad) != 0 { + t.Fatalf("unexpected: %v", bad) + } + if bad := Disagreements([]AnEmitter{{Module: "no-such-seat", Emits: []string{"x"}}}, + []AConsumer{kept}, nil); len(bad) != 1 { + t.Fatalf("an unknown, non-retired consume no longer fails: %v", bad) + } +} + // **Do the derived subjects meet, not just the names?** // // The check above compares what a consumer asks for against what an emitter says it emits, by name. It