A node the sandbox did not judge is a field of the contract: composer.Machine.NotJudged and the answer's verdict not-judged, so the checker decides by them and never by words (ADR 0593 §9; the prepare's seams finding on "not judged")
This commit is contained in:
+10
-6
@@ -135,13 +135,17 @@ type ManifestRead struct {
|
||||
}
|
||||
|
||||
// Machine is one machine composed: whether it composes (resolves, at DepthResolve), why not, the node-engine
|
||||
// validator's problems and the composition's refusals (DepthCompose), and its declared paths when asked.
|
||||
// validator's problems and the composition's refusals (DepthCompose), and its declared paths when asked. NotJudged says,
|
||||
// in words, why the composer did not judge the machine (an older node-engine's input that does not say how it composes,
|
||||
// novox/hq ADR 0593 §9): the machine is then neither composed nor refused, and a reader decides by this field alone,
|
||||
// never by the words of Reason.
|
||||
type Machine struct {
|
||||
Composes bool `json:"composes"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Problems []string `json:"problems,omitempty"`
|
||||
Refusals []string `json:"refusals,omitempty"`
|
||||
Declared []Path `json:"declared,omitempty"`
|
||||
Composes bool `json:"composes"`
|
||||
NotJudged string `json:"not_judged,omitempty"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Problems []string `json:"problems,omitempty"`
|
||||
Refusals []string `json:"refusals,omitempty"`
|
||||
Declared []Path `json:"declared,omitempty"`
|
||||
}
|
||||
|
||||
// Path is one path a declaration puts on the machine, with its kind (the resource's type), owner, group and mode as
|
||||
|
||||
@@ -31,6 +31,12 @@ const (
|
||||
// starting): no module is named, Refused says why in words, and the checker takes it as a node that did not answer
|
||||
// (ComposeNoAnswer, ADR 0593 §9), deciding by this verdict and never by the words.
|
||||
ComposeCandidateUnready = "unready"
|
||||
// ComposeCandidateNotJudged is the verdict for a node the checker's sandbox composed and could not judge (an older
|
||||
// node-engine's input that does not say how it composes, novox/hq ADR 0593 §9): no module is named, Refused says why in
|
||||
// words, and the checker names the node with them and passes the check with that warning, never silent and never a
|
||||
// failure of the change. The checker decides by this verdict, never by the words (ADR 0601 §4's kind: a contract is a
|
||||
// field, not a phrase).
|
||||
ComposeCandidateNotJudged = "not-judged"
|
||||
|
||||
// The states of one module's composition with the candidate: composed (Digest set), refused by the candidate
|
||||
// (Words set), or held, refused without the candidate too (Words set), which counts toward no verdict.
|
||||
@@ -115,13 +121,13 @@ func (a ComposeCandidateAnswer) check() error {
|
||||
if a.Took < 0 {
|
||||
return fmt.Errorf("delivery: the answer of %s took %d ms", a.Node, a.Took)
|
||||
}
|
||||
if a.Verdict == ComposeCandidateUnready && a.Refused == "" {
|
||||
return fmt.Errorf("delivery: %s is not ready to compose and its answer says no why", a.Node)
|
||||
if (a.Verdict == ComposeCandidateUnready || a.Verdict == ComposeCandidateNotJudged) && a.Refused == "" {
|
||||
return fmt.Errorf("delivery: %s's answer is %s and says no why", a.Node, a.Verdict)
|
||||
}
|
||||
if a.Refused != "" {
|
||||
if len(a.Modules) > 0 || a.Verdict != ComposeCandidateRefused && a.Verdict != ComposeCandidateUnready {
|
||||
return fmt.Errorf("delivery: %s could not compose the candidate (%s), and its answer names modules or is neither %s nor %s",
|
||||
a.Node, a.Refused, ComposeCandidateRefused, ComposeCandidateUnready)
|
||||
if len(a.Modules) > 0 || a.Verdict != ComposeCandidateRefused && a.Verdict != ComposeCandidateUnready && a.Verdict != ComposeCandidateNotJudged {
|
||||
return fmt.Errorf("delivery: %s could not compose the candidate (%s), and its answer names modules or is neither %s, %s nor %s",
|
||||
a.Node, a.Refused, ComposeCandidateRefused, ComposeCandidateUnready, ComposeCandidateNotJudged)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -78,6 +78,23 @@ func TestComposeCandidateAndComposedPlanRoundTripAndRefuse(t *testing.T) {
|
||||
if _, err := EncodeComposeCandidateAnswer(unready); err == nil {
|
||||
t.Error("an unready answer naming modules was encoded")
|
||||
}
|
||||
// A node the sandbox did not judge: its own verdict, with words and no module (ADR 0593 §9, ADR 0601 §4).
|
||||
notJudged := ComposeCandidateAnswer{Node: "ace", Candidate: key, Verdict: ComposeCandidateNotJudged, Refused: "its node-engine sends no running state"}
|
||||
if raw, err := EncodeComposeCandidateAnswer(notJudged); err != nil {
|
||||
t.Errorf("a not-judged answer was not encoded: %v", err)
|
||||
} else if back, err := DecodeComposeCandidateAnswer(raw); err != nil || back.Verdict != ComposeCandidateNotJudged {
|
||||
t.Errorf("a not-judged answer read back as %+v, %v", back, err)
|
||||
}
|
||||
for name, mutate := range map[string]func(*ComposeCandidateAnswer){
|
||||
"no why": func(a *ComposeCandidateAnswer) { a.Refused = "" },
|
||||
"modules too": func(a *ComposeCandidateAnswer) { a.Modules = good.Modules },
|
||||
} {
|
||||
a := notJudged
|
||||
mutate(&a)
|
||||
if _, err := EncodeComposeCandidateAnswer(a); err == nil {
|
||||
t.Errorf("a not-judged answer with %s was encoded", name)
|
||||
}
|
||||
}
|
||||
if _, err := DecodeComposeCandidateAnswer([]byte(strings.Replace(string(raw), `"took"`, `"other":1,"took"`, 1))); err == nil {
|
||||
t.Error("an answer with an unknown key was read")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user