Merge branch 'feat/l3-final-b' into feat/l3-final
This commit is contained in:
@@ -1072,4 +1072,14 @@ func aWantWaitsOnTheVerbEdgesTheGraphKeeps(t *testing.T) {
|
||||
t.Errorf("served(%s) = %v, want %v: the running server's manifest serves w alone, late's is not read", v, served(v), want)
|
||||
}
|
||||
}
|
||||
// ADR 0614 §5: bus-state counts as offered only from a healthy build on a node present; the bus module's build on an
|
||||
// offline node offers nothing, and one whose manifest is not read counts its trunk manifest's offer.
|
||||
bus := map[string]catalogue.Manifest{"bus": {Module: "bus", Provides: []catalogue.Offer{{Name: graph.BusState, Scope: catalogue.ScopeMesh}}}}
|
||||
for _, online := range []bool{false, true} {
|
||||
offering := p.offering(context.Background(), get, bus, assign.Nodes{Online: map[string]bool{"n2": online},
|
||||
Haves: map[string]map[string]delivery.Have{"n2": {"bus": at(fp("2"))}}})
|
||||
if offering(graph.BusState) != online {
|
||||
t.Errorf("with the bus module's node online %v, bus-state offered %v", online, offering(graph.BusState))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@ func (m Module) verbWaiting(node string) (string, bool) {
|
||||
// bus-state entry, as the module graph reads it) and no build whose manifest offers bus-state runs healthy on a node
|
||||
// present. The provision bus-state is answered with no credential of a consumer's own, so ADR 0603 §5 counts the
|
||||
// provider's own have and no provisioner key is waited for, handed or not. Nil Offering (nothing read of what runs) waits
|
||||
// for none. It holds under the provisions' rule, its words naming bus state (graph.BusStateWaitWords).
|
||||
// for none, and neither does a module that offers bus-state itself. It holds under the provisions' rule, its words naming bus state (graph.BusStateWaitWords).
|
||||
func (m Module) busStateWaiting(node string) (string, bool) {
|
||||
if len(m.Manifest.BusState) == 0 || m.Offering == nil || m.Offering(graph.BusState) {
|
||||
if len(m.Manifest.BusState) == 0 || m.Offering == nil || m.Offering(graph.BusState) ||
|
||||
slices.Contains(m.Manifest.Offers(), graph.BusState) { // the bus module offering it waits on nobody for it
|
||||
|
||||
return "", false
|
||||
}
|
||||
return graph.BusStateWaitWords(m.Name, node), true
|
||||
|
||||
@@ -161,6 +161,7 @@ func TestEachRuleHoldsTheWantBack(t *testing.T) {
|
||||
// ADR 0614 §5: a module asking bus state is held while no build offering bus-state runs, and moves once one does.
|
||||
{"bus state no running build offers", nil, nil, false, graph.BusState},
|
||||
{"bus state a running build offers", nil, []string{graph.BusState}, false, ""},
|
||||
{"bus state its own module offers", nil, nil, false, ""},
|
||||
} {
|
||||
m, n := ready()
|
||||
m.Invokes = c.invokes
|
||||
@@ -170,6 +171,9 @@ func TestEachRuleHoldsTheWantBack(t *testing.T) {
|
||||
if strings.HasPrefix(c.name, "bus state") {
|
||||
m.Manifest.BusState = []catalogue.BusStateEntry{{Name: "cache", Storage: "key-value"}}
|
||||
m.Offering = func(p string) bool { return slices.Contains(c.served, p) }
|
||||
if c.name == "bus state its own module offers" {
|
||||
m.Manifest.Provides = []catalogue.Offer{{Name: graph.BusState, Scope: catalogue.ScopeMesh}}
|
||||
}
|
||||
}
|
||||
words := graph.VerbWaitWords(c.holds, "mail", "g14")
|
||||
if c.holds == graph.BusState {
|
||||
|
||||
@@ -107,8 +107,9 @@ func tiersToolSaysEachModulesWait(t *testing.T) {
|
||||
if out, err := run(t, r, view.TiersTool, map[string]any{}); err != nil || out.(view.Tiers).Revision != 9 || out.(view.Tiers).Modules != 3 {
|
||||
t.Errorf("view_tiers of the gate's newest = %+v, %v", out, err)
|
||||
}
|
||||
// ADR 0614 §2-§5: a want held on a verb or a reader capability is named by its edge, a wait for bus state as bus state,
|
||||
// and each verb edge the graph leaves out on a cycle is named.
|
||||
// ADR 0614 §2-§5: a want held on a verb, a reader capability or bus state is named by its edge; bus state is no
|
||||
// provisioner key (none is ever made for it), so a module asking it shows no provision wait of it; and each verb edge
|
||||
// the graph leaves out on a cycle is named.
|
||||
r.GraphState = fake{
|
||||
"db": node(graph.Node{FP: fp("a"), Repository: "novox/mesh-catalog", Provides: []string{"database"}}),
|
||||
"web": node(graph.Node{FP: fp("b"), Repository: "novox/mesh-catalog", Requires: []string{"database", graph.BusState}, Awaits: []string{"database", graph.BusState},
|
||||
@@ -127,9 +128,9 @@ func tiersToolSaysEachModulesWait(t *testing.T) {
|
||||
t.Fatalf("view_tiers 9 = %+v, %v", out, err)
|
||||
}
|
||||
web := got.Tiers[1][0]
|
||||
if len(web.Waits) != 3 || web.Waits[0].Edge != edge || web.Waits[1].Edge != "bus state" || !strings.Contains(web.Waits[1].Words, "no key of bus-state") ||
|
||||
if len(web.Waits) != 2 || web.Waits[0].Edge != edge || web.Waits[1].Edge != "provision database" ||
|
||||
!reflect.DeepEqual(web.LeftOut, []string{"db.loop"}) {
|
||||
t.Errorf("web held by %q = %+v, want its want named %s, a bus state wait and db.loop left out", words, web, edge)
|
||||
t.Errorf("web held by %q = %+v, want its want named %s, no wait for a bus-state key and db.loop left out", words, web, edge)
|
||||
}
|
||||
}
|
||||
// The graph not readable: every module in the first tier, said; past 500 modules the answer says it is cut short.
|
||||
|
||||
@@ -57,8 +57,8 @@ type TierModule struct {
|
||||
LeftOut []string `json:"left-out,omitempty"`
|
||||
}
|
||||
|
||||
// TierWait is one thing a module waits on: the edge (build, have, provision <name>, bus state, or for a want held back
|
||||
// want, verb <verb> or reader capability <capabilities> as the assigner's words name it, ADR 0614 §2, §4, §5), the node
|
||||
// TierWait is one thing a module waits on: the edge (build, have, provision <name>, or for a want held back want, verb
|
||||
// <verb>, reader capability <capabilities> or bus state as the assigner's words name it, ADR 0614 §2, §4, §5), the node
|
||||
// it waits on (none for its build), the assigner's rule for a want held back, the part's words and since when, where the
|
||||
// part says it.
|
||||
type TierWait struct {
|
||||
@@ -249,6 +249,11 @@ func (r Reader) waitsOf(module string, m delivery.Module, g graph.Node, wants, p
|
||||
out = append(out, hw)
|
||||
}
|
||||
for _, a := range g.Awaits {
|
||||
if a == graph.BusState {
|
||||
// Bus state is offered with no credential of a consumer's own, so the provisioner keys nothing for it: its wait is
|
||||
// the assigner's held want alone, named bus state from its words (ADR 0614 §5).
|
||||
continue
|
||||
}
|
||||
out = append(out, provisionWaits(node, module, a, provided, perr)...)
|
||||
}
|
||||
}
|
||||
@@ -323,9 +328,6 @@ func (r Reader) haveWait(node, module, fp string) (TierWait, bool) {
|
||||
// provisionWaits are the waits of the provision a that module awaits on node: none once every key of it is provided.
|
||||
func provisionWaits(node, module, a string, provided map[string]json.RawMessage, perr error) []TierWait {
|
||||
edge := "provision " + a
|
||||
if a == graph.BusState {
|
||||
edge = "bus state" // a bus-state entry of the manifest (ADR 0614 §5)
|
||||
}
|
||||
if perr != nil {
|
||||
return []TierWait{{Edge: edge, Node: node, Words: "the provisioner's keys cannot be read: " + perr.Error()}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user