The check's composer says a node's refusal in the words of its composition with the lifted modules held (issue 1921, milestone 47/G)
When a node refused also with the modules composed without their build held as its node-engine holds them, the verdict kept the words of the composition from their unbuilt manifests, whose refusals the lift itself made (a tool runner with no bundle, a resource whose artifact or template no build resolved). In the group check of c5d32074c945 that hid lab's real refusal on shanks among them. The node's refusal is now that of the held composition, named so. Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -241,11 +241,17 @@ func runCase(r Request, c Case, depth string) (CaseVerdict, error) {
|
|||||||
// Composed without the build it runs at: named per node and module, never a silent pass (issue 1921). The
|
// Composed without the build it runs at: named per node and module, never a silent pass (issue 1921). The
|
||||||
// machine is then not judged, as for a node whose running state its engine does not send (ADR 0593 §9). Where
|
// machine is then not judged, as for a node whose running state its engine does not send (ADR 0593 §9). Where
|
||||||
// it does not compose without that build (a tool runner's bundle), it is composed with the module held as its
|
// it does not compose without that build (a tool runner's bundle), it is composed with the module held as its
|
||||||
// node-engine holds it, and named so; a node that refuses then too is the change's refusal.
|
// node-engine holds it, and named so; a node that refuses then too is the change's refusal, in the words of that
|
||||||
|
// composition, never of the one from the unbuilt manifests, whose refusals the lift itself made (a tool runner
|
||||||
|
// with no bundle, a resource whose artifact or template no build resolved: the group check of c5d32074c945 on
|
||||||
|
// shanks).
|
||||||
how := "composed from the change's manifest without its build: "
|
how := "composed from the change's manifest without its build: "
|
||||||
if !m.Composes && m.NotJudged == "" {
|
if !m.Composes && m.NotJudged == "" {
|
||||||
if again := machine(heldAgain(in, held, awaited), node, depth, r.Declarations); again.Composes {
|
switch again := machine(heldAgain(in, held, awaited), node, depth, r.Declarations); {
|
||||||
|
case again.Composes:
|
||||||
m, how = again, "composed with it held as its node-engine holds it, since it does not compose without its build: "
|
m, how = again, "composed with it held as its node-engine holds it, since it does not compose without its build: "
|
||||||
|
case again.NotJudged == "":
|
||||||
|
m, how = again, "refused with it held as its node-engine holds it, since it does not compose without its build: "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
words = how + words
|
words = how + words
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"git.novox.be/novox/mesh-contracts/go/seats/meshmoduleassigner"
|
"git.novox.be/novox/mesh-contracts/go/seats/meshmoduleassigner"
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||||
@@ -317,30 +318,50 @@ func TestARequestItCannotRunIsRefused(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
runner := `{"module": "app", "version": "1", "tool-runner": true, ` +
|
||||||
|
`"build": {"artifacts": [{"name": "runtime", "kind": "bundle", "language": "go", "from": "cmd/runner", "binary": "runner"}]}}`
|
||||||
for _, row := range []struct {
|
for _, row := range []struct {
|
||||||
name, raw, digest string
|
name, raw, digest string
|
||||||
words string // in NotJudged, its build's paths not declared; "" composes at its build
|
words string // in NotJudged, its build's paths not declared; "" composes at its build
|
||||||
|
beside string // a module the change refuses on the same node: words are then in the refusal
|
||||||
}{
|
}{
|
||||||
{"the digest of the case's manifest", plain, same, ""},
|
{"the digest of the case's manifest", plain, same, "", ""},
|
||||||
{"another digest, the same contract", plain, strings.Repeat("b", 64), "of another manifest than the change's (its build was made of the manifest " + strings.Repeat("b", 64)},
|
{"another digest, the same contract", plain, strings.Repeat("b", 64), "of another manifest than the change's (its build was made of the manifest " + strings.Repeat("b", 64), ""},
|
||||||
{"no digest, the same contract", plain, "", ""},
|
{"no digest, the same contract", plain, "", "", ""},
|
||||||
{"no digest, another contract", strings.Replace(plain, `"version": "1"`, `"version": "2"`, 1), "",
|
{"no digest, another contract", strings.Replace(plain, `"version": "1"`, `"version": "2"`, 1), "",
|
||||||
"app is composed by the running node-engine at its build fp1, of another manifest than the change's (its node-engine names no manifest"},
|
"app is composed by the running node-engine at its build fp1, of another manifest than the change's (its node-engine names no manifest", ""},
|
||||||
{"a tool runner, its bundle awaited", `{"module": "app", "version": "1", "tool-runner": true, ` +
|
{"a tool runner, its bundle awaited", runner, "",
|
||||||
`"build": {"artifacts": [{"name": "runtime", "kind": "bundle", "language": "go", "from": "cmd/runner", "binary": "runner"}]}}`, "",
|
"composed with it held as its node-engine holds it, since it does not compose without its build: app is composed by the running node-engine at its build fp1", ""},
|
||||||
"composed with it held as its node-engine holds it, since it does not compose without its build: app is composed by the running node-engine at its build fp1"},
|
// The group check of c5d32074c945, shanks: the change refused lab there, and the words were those of the
|
||||||
|
// composition from the change's manifests unbuilt ("mesh-build-go runs as its own account and its build
|
||||||
|
// produced no bundle to serve"), not of the one with them held, so the lift's own refusals failed the node.
|
||||||
|
{"a tool runner awaited beside a module the change refuses", runner, "",
|
||||||
|
"refused with it held as its node-engine holds it, since it does not compose without its build: app is composed by the running node-engine at its build fp1",
|
||||||
|
`{"module": "office", "version": "1", "resources": [{"id": "c", "type": "file", "path": "/etc/office.conf", "template": "x"}]}`},
|
||||||
} {
|
} {
|
||||||
in := compose.Input{Catalogue: map[string]catalogue.Manifest{"app": built}, Nodes: []compose.Node{{Name: "a", Assigned: []string{"app"}}},
|
in := compose.Input{Catalogue: map[string]catalogue.Manifest{"app": built}, Nodes: []compose.Node{{Name: "a", Assigned: []string{"app"}}},
|
||||||
ComposedHow: &compose.ComposedHow{Node: "a", Builds: map[string]string{"app": "fp1"}}}
|
ComposedHow: &compose.ComposedHow{Node: "a", Builds: map[string]string{"app": "fp1"}}}
|
||||||
if row.digest != "" {
|
if row.digest != "" {
|
||||||
in.ComposedHow.Manifests = map[string]string{"app": row.digest}
|
in.ComposedHow.Manifests = map[string]string{"app": row.digest}
|
||||||
}
|
}
|
||||||
|
manifests := map[string]Manifest{"app": {Raw: json.RawMessage(row.raw)}}
|
||||||
|
if row.beside != "" {
|
||||||
|
manifests["office"] = Manifest{Raw: json.RawMessage(row.beside)}
|
||||||
|
in.Nodes[0].Assigned = append(in.Nodes[0].Assigned, "office")
|
||||||
|
}
|
||||||
v, err := Run(withInput(t, Request{V: Version, Machines: []string{"a"}, Depth: DepthCompose, Declarations: true,
|
v, err := Run(withInput(t, Request{V: Version, Machines: []string{"a"}, Depth: DepthCompose, Declarations: true,
|
||||||
Cases: []Case{{Name: "change", Manifests: map[string]Manifest{"app": {Raw: json.RawMessage(row.raw)}}}}}, in))
|
Cases: []Case{{Name: "change", Manifests: manifests}}}, in))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
m := v.Cases[0].Machines["a"]
|
m := v.Cases[0].Machines["a"]
|
||||||
|
if row.beside != "" {
|
||||||
|
said := fmt.Sprint(m.Reason, m.Problems, m.Refusals)
|
||||||
|
if m.Composes || m.NotJudged != "" || !strings.Contains(said, "office") || strings.Contains(said, "bundle") || !strings.Contains(m.Reason, row.words) {
|
||||||
|
t.Errorf("%s: machine %+v, want the change's refusal of office with app held, naming %q", row.name, m, row.words)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
declared := false
|
declared := false
|
||||||
for _, p := range m.Declared {
|
for _, p := range m.Declared {
|
||||||
declared = declared || p.Path == "/var/lib/app-built"
|
declared = declared || p.Path == "/var/lib/app-built"
|
||||||
|
|||||||
Reference in New Issue
Block a user