89 lines
4.4 KiB
Go
89 lines
4.4 KiB
Go
package manifest
|
|
|
|
import (
|
|
"os"
|
|
"reflect"
|
|
"slices"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
func load(t *testing.T) catalogue.Manifest {
|
|
t.Helper()
|
|
raw, err := os.ReadFile("module.json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m, err := catalogue.ParseManifest(raw)
|
|
if err != nil {
|
|
t.Fatalf("mesh-sdk's manifest reader refuses the manifest: %v", err)
|
|
}
|
|
return m
|
|
}
|
|
|
|
// 1297/B2a: the controller's reader (mesh-sdk catalogue, which the controller reads manifests with) takes the
|
|
// manifest; it reads exactly the buckets the assigner opens (the program's list, held equal in its own test), keeps
|
|
// the states it declares (the differences kept read-only, 1906/D5), and holds a credential of its own.
|
|
func TestManifest(t *testing.T) {
|
|
m := load(t)
|
|
if m.Module != "mesh-delivery-assigner" {
|
|
t.Errorf("module = %q", m.Module)
|
|
}
|
|
reads := slices.Clone(m.Reads)
|
|
slices.Sort(reads)
|
|
want := []string{"mesh-build-go.steps", "mesh-config.resolved", "mesh-controller.assignments", "mesh-controller.builds", "mesh-controller.composed", "mesh-controller.grants",
|
|
"mesh-delivery-builder.builds", "mesh-delivery-indexer.candidates", "mesh-delivery-indexer.manifests",
|
|
"mesh-delivery-indexer.modules", "mesh-delivery-teller.answers", "mesh-delivery-watchman.presence", "node-engine.have"}
|
|
if !reflect.DeepEqual(reads, want) {
|
|
t.Errorf("reads = %v, want exactly %v", reads, want)
|
|
}
|
|
states := map[string]int{}
|
|
for _, s := range m.State {
|
|
states[s.Name] = s.History
|
|
}
|
|
if want := map[string]int{"asks": 5, "compositions": 5, "differences": 64, "puts": 20, "wants": 20,
|
|
"placement": 64, "proposals": 5, "candidates": 5, "pulses": 0}; !reflect.DeepEqual(states, want) {
|
|
t.Errorf("state = %v, want %v", states, want)
|
|
}
|
|
if _, ok := m.OwnSecrets["broker"]; !ok || len(m.OwnSecrets) != 1 {
|
|
t.Errorf("own-secrets = %v, want exactly broker (or no credential is issued)", m.OwnSecrets)
|
|
}
|
|
if m.SecretsOwner != "mesh-delivery-assigner" {
|
|
t.Errorf("secrets-owner = %q", m.SecretsOwner)
|
|
}
|
|
// 1906/D3: it says its conditions on the operator channel; 1622: it puts its compose asks on the Go build seat, as the
|
|
// checker puts its checks.
|
|
if !slices.Equal(m.Uses, []string{"node-build-go", "operator-channel"}) {
|
|
t.Errorf("uses = %v, want exactly node-build-go and operator-channel", m.Uses)
|
|
}
|
|
// ADR 0546: it serves its own tools (put, release, puts) from its bundle through the tool runner (the artifact loads the
|
|
// module), says each put's step as the event put, and calls the controller's warranted and the bus node's backup holder.
|
|
// ADR 0567 §1, §6-§10: it holds the seat mesh-placement, serving its seven verbs; keeps the seat's events on its stream
|
|
// placement for 30 days; calls the controller's export, its four verbs that keep its assignments in step and its
|
|
// hand-act log; and reads mesh-config's resolved values to compose every node a proposal touches.
|
|
if len(m.Claims) != 1 || m.Claims[0].Name != catalogue.PlacementSeat || m.Claims[0].At() != catalogue.ScopeMesh ||
|
|
!slices.Equal(m.Claims[0].Serves, []string{"placement", "proposals", "propose", "withdraw", "again", "adopt", "hand-back"}) {
|
|
t.Errorf("the assigner claims %+v, want mesh-placement with its seven verbs", m.Claims)
|
|
}
|
|
if seat, _ := catalogue.SeatNamed(catalogue.PlacementSeat); catalogue.CanHold(m, seat) != nil {
|
|
t.Errorf("the assigner cannot hold the seat: %v", catalogue.CanHold(m, seat))
|
|
}
|
|
if !slices.Equal(m.Tools, []string{"assigner_put", "assigner_release", "assigner_puts"}) {
|
|
t.Errorf("the assigner serves tools %v, want its three put tools", m.Tools)
|
|
}
|
|
if len(m.Streams) != 1 || m.Streams[0].Name != delivery.PlacementStream || m.Streams[0].MaxAgeDays != delivery.PlacementStreamDays ||
|
|
!slices.Equal(slices.Sorted(slices.Values(m.Streams[0].Events)), slices.Sorted(slices.Values(delivery.PlacementEvents))) {
|
|
t.Errorf("streams = %+v, want placement carrying the seat's four events for %d days", m.Streams, delivery.PlacementStreamDays)
|
|
}
|
|
if want := []string{"seat:mesh-controller.assign", "seat:mesh-controller.hand-act", "seat:mesh-controller.pin",
|
|
"seat:mesh-controller.placement-export", "seat:mesh-controller.unassign", "seat:mesh-controller.unpin",
|
|
"seat:mesh-controller.warranted", "seat:node-backup.backed-up", "seat:node-backup.now"}; !slices.Equal(slices.Sorted(slices.Values(m.Invokes)), want) {
|
|
t.Errorf("invokes = %v, want %v", m.Invokes, want)
|
|
}
|
|
if !slices.Equal(m.Emits, []string{"put"}) {
|
|
t.Errorf("emits = %v, want put", m.Emits)
|
|
}
|
|
}
|