mesh/delivery ready: it is merged on the Approve
mesh/check pass 09d6070ebd86 on 45e143fba672 | unit 796 run, 1280 kept, 1 skipped | integration 802 run, 1377 kept, 1 skipped | over bound: unit (slow…
mesh/delivery-group group fix/47-G-reader-release-2 ready: every member ready, and composed together they pass
G's builder and checker follow the assigner's views by the seat, seat:mesh-module-assigner.views.assignments; SeatViewConsume splits that form, and a seat compiled from its definition names the states it offers as views, which the validator checks the form against. Builds: design 47 G §621, §616, §699 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
102 lines
5.5 KiB
Go
102 lines
5.5 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"encoding/json"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/seatdef"
|
|
)
|
|
|
|
// A manifest carrying the words design 47 G writes is read whole by the reader release (design 47 G §340, §409):
|
|
// `version` as MAJOR.MINOR (§368), a `*` emitter in `consumes` (§386), an observer's finding stream (§387) and an
|
|
// artifact's `needs` (§47, §432).
|
|
func TestTheReaderReleaseReadsTheManifestWordsGWrites(t *testing.T) {
|
|
m, err := decodeForTest([]byte(`{"module":"mesh-watcher","version":"1.4","needs-approval":["restart","node-engine.composition","finding-written"],` +
|
|
`"consumes":["*.finding-written","mesh-conditions.findings-asked"],` +
|
|
`"streams":[{"name":"mesh-watcher-findings","events":["finding-written","finding-cleared","findings-stated"],"max-age-days":7,"max-mib":16}],` +
|
|
`"build":{"artifacts":[{"name":"program","kind":"bundle","language":"go","needs":["mesh-grants:program","node-tools:runtime"]}]}}`))
|
|
if err != nil {
|
|
t.Fatalf("a manifest with G's words was refused: %v", err)
|
|
}
|
|
if len(m.UnknownField()) != 0 || len(m.NeedsApproval) != 3 {
|
|
t.Fatalf("a word was set aside: %v (needs-approval %v)", m.UnknownField(), m.NeedsApproval)
|
|
}
|
|
if m.Version != "1.4" || m.Consumes[0] != "*.finding-written" || m.Streams[0].Name != "mesh-watcher-findings" ||
|
|
len(m.Build.Artifacts[0].Needs) != 2 || m.Build.Artifacts[0].Needs[0] != "mesh-grants:program" {
|
|
t.Fatalf("read as %+v", m)
|
|
}
|
|
}
|
|
|
|
// The second reader release reads the words G's manifests write beyond the first's (design 47 G §494, §621): each row a
|
|
// manifest read whole, or refused naming what is wrong, and what the reader gives of it.
|
|
func TestTheSecondReaderReleaseReadsGsManifestWords(t *testing.T) {
|
|
for _, c := range []struct {
|
|
name, raw, refused string
|
|
check func(Manifest) bool
|
|
}{
|
|
{name: "a state's cap (§469)", raw: `{"module":"m","version":"1.0","state":["plain",{"name":"pipelines","max-mib":256}]}`,
|
|
check: func(m Manifest) bool { return m.State[0].MaxMiB == 0 && m.State[1].MaxMiB == 256 }},
|
|
{name: "a state's cap out of the objects section's bounds (§469)",
|
|
raw: `{"module":"m","version":"1.0","state":[{"name":"pipelines","max-mib":0}]}`, refused: "max-mib is between 1 and 8192"},
|
|
{name: "a package's calls and the tool runner's states (§605, §545)",
|
|
raw: `{"module":"m","version":"1.0","build":{"artifacts":[{"name":"go","kind":"package","language":"go","calls":["put-sessions"]},` +
|
|
`{"name":"runtime","kind":"bundle","language":"go","states":["put-sessions","finding-calls"]}]}}`,
|
|
check: func(m Manifest) bool {
|
|
a := m.Build.Artifacts
|
|
return len(a) == 2 && len(a[0].Calls) == 1 && a[0].Calls[0] == "put-sessions" && len(a[1].States) == 2
|
|
}},
|
|
{name: "* with two long-form invokes (§617)",
|
|
raw: `{"module":"m","version":"1.0","invokes":["*",{"verb":"seat:mesh-catalog.revision","fields":["none-yet"]},` +
|
|
`{"verb":"seat:mesh-catalog.entry"}]}`,
|
|
check: func(m Manifest) bool {
|
|
out, _ := json.Marshal(m)
|
|
return slices.Equal(m.Invokes, []string{"*", "seat:mesh-catalog.revision", "seat:mesh-catalog.entry"}) &&
|
|
len(m.InvokeFields) == 1 && slices.Equal(m.InvokeFields["seat:mesh-catalog.revision"], []string{"none-yet"}) &&
|
|
strings.Contains(string(out), `"invokes":["*",{"verb":"seat:mesh-catalog.revision","fields":["none-yet"]},"seat:mesh-catalog.entry"]`)
|
|
}},
|
|
{name: "a long-form invoke with a word it does not know (§617)",
|
|
raw: `{"module":"m","version":"1.0","invokes":[{"verb":"seat:mesh-catalog.revision","field":["none-yet"]}]}`,
|
|
refused: `invokes[0]: a verb, or {verb, fields}`},
|
|
} {
|
|
m, err := decodeForTest([]byte(c.raw))
|
|
switch {
|
|
case c.refused != "" && (err == nil || !strings.Contains(err.Error(), c.refused)):
|
|
t.Errorf("%s: read as %v, want refused naming %q", c.name, err, c.refused)
|
|
case c.refused == "" && err != nil:
|
|
t.Errorf("%s: refused: %v", c.name, err)
|
|
case c.refused == "" && (len(m.UnknownField()) != 0 || !c.check(m)):
|
|
t.Errorf("%s: read as %+v (set aside %v)", c.name, m, m.UnknownField())
|
|
}
|
|
}
|
|
}
|
|
|
|
// A consumed view of a seat, `seat:<seat>.views.<state>`, is read apart from a consumed event, and a seat's compiled form
|
|
// names the states its definition offers as views (design 47 G §616, §699, §621).
|
|
func TestTheSecondReaderReleaseReadsASeatNamedView(t *testing.T) {
|
|
for _, row := range []struct {
|
|
consume, seat, state string
|
|
ok, bad bool
|
|
}{
|
|
{"seat:mesh-module-assigner.views.assignments", "mesh-module-assigner", "assignments", true, false},
|
|
{"mesh-delivery-assigner.views.assignments", "", "", false, false},
|
|
{"seat:mesh-module-assigner.assignments", "", "", true, true},
|
|
{"seat:.views.assignments", "", "", true, true},
|
|
} {
|
|
seat, state, ok, err := SeatViewConsume(row.consume)
|
|
if seat != row.seat || state != row.state || ok != row.ok || (err != nil) != row.bad {
|
|
t.Errorf("SeatViewConsume(%q) = %q, %q, %v, %v", row.consume, seat, state, ok, err)
|
|
}
|
|
}
|
|
m, err := decodeForTest([]byte(`{"module":"m","version":"1.0","consumes":["seat:mesh-module-assigner.views.assignments"]}`))
|
|
if err != nil || len(m.UnknownField()) != 0 || m.Consumes[0] != "seat:mesh-module-assigner.views.assignments" {
|
|
t.Errorf("a seat-named view in consumes read as %v, %v", m.Consumes, err)
|
|
}
|
|
s := SeatFromDefinition(seatdef.Definition{Seat: "mesh-module-assigner", Scope: "mesh",
|
|
States: []seatdef.State{{Name: "assignments", View: true}, {Name: "placement"}}})
|
|
if !slices.Equal(s.Views, []string{"assignments"}) {
|
|
t.Errorf("the seat's views = %v", s.Views)
|
|
}
|
|
}
|