V4 judge-not-managed: a config value with neither a default nor required is accepted

Builds: design 42 zfs-owns-zfs §11; answer A-14
This commit is contained in:
2026-11-13 01:27:58 +01:00
parent e9eac06e5d
commit e1db8701b5
2 changed files with 8 additions and 7 deletions
+3 -5
View File
@@ -724,13 +724,11 @@ func ConfigProblems(m catalogue.Manifest) []string {
if strings.TrimSpace(d.Description) == "" { if strings.TrimSpace(d.Description) == "" {
say("no description: say in a sentence what the value is, including its unit (novox/hq ADR 0348 §4)") say("no description: say in a sentence what the value is, including its unit (novox/hq ADR 0348 §4)")
} }
switch { // A value with neither a default nor `required` is not managed until it is set (design 42 zfs-owns-zfs §11,
case d.Required && d.Default != nil: // answer A-14).
if d.Required && d.Default != nil {
say("both a default and required: a required value is the operator's own and has no default; give " + say("both a default and required: a required value is the operator's own and has no default; give " +
"one or the other (novox/hq ADR 0348 §4)") "one or the other (novox/hq ADR 0348 §4)")
case !d.Required && d.Default == nil:
say("neither a default nor required: give a default, or say \"required\": true for a value that is " +
"the operator's own (novox/hq ADR 0348 §4)")
} }
if as := renamed[key]; as != "" && d.Required { if as := renamed[key]; as != "" && d.Required {
say("is laid into its file as %q, and only when it is set, so the file and its code fall back when "+ say("is laid into its file as %q, and only when it is set, so the file and its code fall back when "+
@@ -3497,11 +3497,14 @@ func caseConfigRefusesAValueNeitherPlacedNorReadAtRuntime(t *testing.T) {
} }
} }
// Rule 2: a value with neither a default nor required. // Rule 2: a value with both a default and required is refused; one with neither is not managed until set (design 42
// zfs-owns-zfs §11, V4/AC1, answer A-14).
func caseConfigRefusesAValueWithNeitherDefaultNorRequired(t *testing.T) { func caseConfigRefusesAValueWithNeitherDefaultNorRequired(t *testing.T) {
m := inConfigForm() m := inConfigForm()
delete(declaration(m, "width"), "default") delete(declaration(m, "width"), "default")
refused(t, m, `"width"`, "neither a default nor required") if _, err := parseRaw(t, m); err != nil {
t.Fatal(err)
}
m = inConfigForm() m = inConfigForm()
declaration(m, "sender")["default"] = "noreply@example.org" declaration(m, "sender")["default"] = "noreply@example.org"
refused(t, m, `"sender"`, "both a default and required") refused(t, m, `"sender"`, "both a default and required")