package broker import ( "encoding/json" "os" "path/filepath" "strings" "testing" ) // **Do the catalogue's emitters and consumers agree?** // // This is the check whose absence let issue 127 stand: every manifest was individually well-formed, // every derivation individually correct, and no cross-module subscription in the mesh matched // anything. A subscription that matches nothing is not an error — it is silence — so nothing // anywhere reported it. // // It compares what one manifest asks to hear against what another says it emits. It cannot demand // that every consumed event have a live emitter, because a module lives in its own repository and // may be registered long before the one whose events it wants. Where the emitter *is* here, it must // emit what the consumer asked for. func TestTheCataloguesEmittersAndConsumersAgree(t *testing.T) { emitters, consumers, seats := theCataloguesEvents(t) if bad := Disagreements(emitters, consumers, seats); len(bad) > 0 { t.Fatalf("%d subscription(s) in the catalogue would match nothing:\n %s", len(bad), strings.Join(bad, "\n ")) } } // And the check itself catches the thing it exists for, so it cannot pass by doing nothing. func TestTheAgreementCheckCatchesASubscriptionThatMatchesNothing(t *testing.T) { bad := Disagreements( []AnEmitter{{Module: "builder", Emits: []string{"built"}}}, []AConsumer{{Module: "mesh-catalog", Consumes: []string{"builder.finished"}}}, nil) if len(bad) != 1 { t.Fatalf("a consumer asking for an event its emitter does not emit was not caught: %v", bad) } if !strings.Contains(bad[0], "builder.finished") || !strings.Contains(bad[0], "built") { t.Fatalf("the report names neither what was asked for nor what is emitted: %s", bad[0]) } // A module that is not here is not a disagreement: it may be registered later. if bad := Disagreements(nil, []AConsumer{{Module: "plex", Consumes: []string{"sonarr.download.completed"}}}, nil); len(bad) != 0 { t.Fatalf("a consumer whose emitter is not installed was reported: %v", bad) } // A wildcard over emitters is deliberate and names no particular event to check. if bad := Disagreements([]AnEmitter{{Module: "sonarr", Emits: []string{"download.completed"}}}, []AConsumer{{Module: "plex", Consumes: []string{"*.download.completed"}}}, nil); len(bad) != 0 { t.Fatalf("a wildcard over emitters was reported: %v", bad) } // An event published under a seat's name is real even though no module declares it as its own. if bad := Disagreements(nil, []AConsumer{{Module: "watcher", Consumes: []string{"mesh-artifact-store.image.pushed"}}}, []DeclaredSeat{{Name: "mesh-artifact-store", Emits: []string{"image.pushed"}}}); len(bad) != 0 { t.Fatalf("an event a seat emits was reported as matching nothing: %v", bad) } } func theCataloguesEvents(t *testing.T) ([]AnEmitter, []AConsumer, []DeclaredSeat) { t.Helper() root := filepath.Join("..", "..", "..", "mesh-catalog", "modules") entries, err := os.ReadDir(root) if err != nil { t.Skipf("catalogue sibling not present: %v", err) } var emitters []AnEmitter var consumers []AConsumer var seats []DeclaredSeat for _, e := range entries { if !e.IsDir() { continue } raw, err := os.ReadFile(filepath.Join(root, e.Name(), "module.json")) if err != nil { continue } var m struct { Module string `json:"module"` Emits []string `json:"emits"` Consumes []string `json:"consumes"` Seats []struct { Name string `json:"name"` Emits []string `json:"emits"` } `json:"seats"` } if err := json.Unmarshal(raw, &m); err != nil { t.Fatalf("%s: %v", e.Name(), err) } if len(m.Emits) > 0 { emitters = append(emitters, AnEmitter{Module: m.Module, Emits: m.Emits}) } if len(m.Consumes) > 0 { consumers = append(consumers, AConsumer{Module: m.Module, Consumes: m.Consumes}) } for _, s := range m.Seats { seats = append(seats, DeclaredSeat{Name: s.Name, Emits: s.Emits}) } } if len(emitters) == 0 { t.Skip("no manifests found beside this checkout") } return emitters, consumers, seats }