package buscompose // The fixtures the copied bus composer is held to (issue 1377, ADR 0547 ยง5): the same source is compiled into the // controller's internal/broker to write the expected lists, and into mesh-sdk's buscompose to compare against them. // UserListFixture is one mesh's records, and the hashes its accounts carry. type UserListFixture struct { Name string Records Records // Hashless are users given no hash, so they are left out and named. Hashless []string } func fixtureTelegramSeat() Seat { return Seat{Name: "telegram-sender", Accepts: []string{"send"}, Emits: []string{"delivered", "failed"}} } // UserListFixtures are the meshes, from the controller's own tests' records outward. func UserListFixtures() []UserListFixture { return []UserListFixture{ {Name: "empty"}, {Name: "the controller's someRecords", Records: Records{ Nodes: []string{"two", "one"}, Assigned: map[string][]Declared{ "one": {{Module: "telegram", Serves: []string{"status"}}}, "two": {{Module: "shop", Emits: []string{"order.placed"}}}, }, Enrolling: []string{"three"}, People: map[string][]string{"ada": {"mesh-catalog.catalog_tools"}}, }}, {Name: "seats, consumers, people and a hashless user", Hashless: []string{"two.audit"}, Records: Records{ Nodes: []string{"one", "two"}, Assigned: map[string][]Declared{ "one": { {Module: "telegram", Holds: []Seat{fixtureTelegramSeat()}, Serves: []string{"status"}}, {Module: "nats", SnapshotsTheBus: true, Serves: []string{"nats_streams"}}, {Module: "mesh-watchman"}, {Module: "mesh-grants", Emits: []string{"membership-changed"}}, }, "two": { {Module: "shop", Uses: []Seat{fixtureTelegramSeat()}, Emits: []string{"order.placed"}}, {Module: "audit", Consumes: []string{"shop.order.placed"}}, }, }, People: map[string][]string{"ada": {"*"}, "bob": {"shop.status"}}, Interchangeable: map[string]bool{"shop": true}, }}, {Name: "state, logs, streams, queues and processes", Records: Records{ Nodes: []string{"ace", "novox"}, Assigned: map[string][]Declared{ "novox": { {Module: "mesh-delivery-builder", Emits: []string{"built"}, State: []Bucket{{Module: "mesh-delivery-builder", Name: "steps", History: 5}, {Module: "mesh-delivery-builder", Name: "presence", PerMachine: true, KeyTTL: true, TTLSeconds: 60}}, Logs: []Log{{Module: "mesh-delivery-builder", Name: "builds", MaxMiB: 64}}, Streams: []ModuleStream{{Module: "mesh-delivery-builder", Name: "asks", Events: []string{"ask"}, MaxAgeDays: 7, MaxMiB: 32, WorkQueue: true}}, Queues: []QueueOwner{{Process: "worker", Stream: "asks", MaxDeliver: 5}}, Processes: []ProcessPrincipal{{Process: "worker", Emits: []string{"built"}, Queues: []QueueOwner{{Process: "worker", Stream: "asks", MaxDeliver: 5}}, State: []string{"steps"}, Invokes: []string{"gitea.gitea_commit"}}}, Invokes: []string{"gitea.gitea_commit"}, }, {Module: "mesh-delivery-view", Reads: []string{"mesh-delivery-builder.steps"}, KeyedReads: []KeyedRead{{Read: "mesh-delivery-builder.presence", Key: "novox"}}}, }, "ace": { {Module: "plex", Serves: []string{"plex_status"}, Checks: []string{"plex.plex_status"}}, {Module: "silent", NoAccount: true}, }, }, RootFree: map[string]bool{"ace": true}, }}, } } // HashOf is the stand-in hash a fixture's user carries. func HashOf(user string) string { h := "$2a$11$" for len(h) < 29 { h += user } return h[:29] + "fixturefixturefixturefixture00" } // ComposedFor is a fixture's user list as the composer writes it, and the users left out. func ComposedFor(f UserListFixture) (string, []string, error) { users, err := Users(f.Records) if err != nil { return "", nil, err } hashes := map[string]string{} skip := map[string]bool{} for _, u := range f.Hashless { skip[u] = true } for _, u := range users { if !skip[u.Username()] { hashes[u.Username()] = HashOf(u.Username()) } } filled, missing := WithPasswords(users, hashes) list, err := ComposeAccounts(filled) return list, missing, err } // MembershipsFor is every membership a fixture's records issue, by `.`, as the composer makes them. func MembershipsFor(f UserListFixture) map[string]Membership { where := PlacementsOf(f.Records, f.Records.Interchangeable) out := map[string]Membership{} for node, ds := range f.Records.Assigned { for _, d := range ds { out[node+"."+d.Module] = MembershipFor(node, d, where) } } return out }