Leave out a module whose stored manifest has an unknown field, and raise it (hq ADR 0262 review)
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/setting-defaults failed: a member failed
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/setting-defaults failed: a member failed
A key dropped silently ran a module without what its manifest says, and a key inside a block still failed the whole catalogue. Judge a key by what it is about, and narrow the listing to one machine.
This commit is contained in:
@@ -218,18 +218,24 @@ func TestANodeCalledDefaultIsANodesLayer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The operator's own value is told by a whole word of the key's name, not by a part of one.
|
||||
func TestAKeyIsTheOperatorsByAWholeWord(t *testing.T) {
|
||||
// The operator's own value is told by what a key's name is about: its last word, or its last two as
|
||||
// a known compound; a plural as its singular; and never a number or a switch.
|
||||
func TestAKeyIsTheOperatorsByWhatItIsAbout(t *testing.T) {
|
||||
for _, key := range []string{"max-tokens", "show-hostname", "ghost-opacity", "users-per-page", "mailbox-size",
|
||||
"font-size", "width", "keyboard-delay", "ipv6-preferred", "client-width"} {
|
||||
"font-size", "width", "keyboard-delay", "ipv6-preferred", "client-width", "user-agent", "url-timeout",
|
||||
"site-title", "cert-renewal-days", "name", "font-name"} {
|
||||
if w := operatorsWord(key); w != "" {
|
||||
t.Errorf("%s read as the operator's (%s)", key, w)
|
||||
}
|
||||
}
|
||||
for key, word := range map[string]string{"mail-domain": "mail", "site-domain": "domain", "api-key": "key", "admin-password": "password",
|
||||
for key, word := range map[string]string{"mail-domain": "domain", "api-key": "key", "admin-password": "password",
|
||||
"oauth-client-id": "client-id", "db-dsn": "dsn", "public-ip": "ip", "puid": "puid", "dns-zone": "zone",
|
||||
"webhook": "webhook", "notify_phone": "phone", "cors.origin": "origin", "smtp-pass": "pass",
|
||||
"backup-passphrase": "passphrase", "data-owner": "owner", "fqdn": "fqdn", "tenant": "tenant", "host": "host"} {
|
||||
"backup-passphrase": "passphrase", "data-owner": "owner", "fqdn": "fqdn", "tenant": "tenant", "host": "host",
|
||||
"allowed-hosts": "host", "admin-emails": "email", "tokens": "token", "hostname": "hostname",
|
||||
"apikey": "apikey", "servername": "servername", "tls-cert": "cert", "site": "site", "timezone": "timezone",
|
||||
"bearer": "bearer", "bind-ipv4": "ipv4", "listen-ipv6": "ipv6", "site-name": "site-name",
|
||||
"server-name": "server-name", "public-name": "public-name", "smtp-relay": "smtp-relay"} {
|
||||
if w := operatorsWord(key); w != word {
|
||||
t.Errorf("%s: read %q, want %q", key, w, word)
|
||||
}
|
||||
@@ -279,22 +285,50 @@ func TestADefaultFillsAContributionAndAServedFactButNotALiteral(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// A stored manifest with a key this controller does not know is read without it, and said; the module
|
||||
// check still refuses it.
|
||||
func TestAStoredManifestWithAnUnknownKeyIsReadAndRegistrationRefusesIt(t *testing.T) {
|
||||
raw := []byte(`{"module": "later", "version": "1", "tools": ["later_x"], "a-field-from-later": {"x": 1}}`)
|
||||
var m Manifest
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatalf("a stored manifest with an unknown key was not read: %v", err)
|
||||
}
|
||||
if m.Module != "later" || len(m.Tools) != 1 || !strings.Contains(m.UnknownField(), `"a-field-from-later"`) {
|
||||
t.Fatalf("read as %+v, unknown %q", m, m.UnknownField())
|
||||
}
|
||||
if _, err := ParseManifest(raw); err == nil || !strings.Contains(err.Error(), `unknown field "a-field-from-later"`) {
|
||||
t.Fatalf("registration took it: %v", err)
|
||||
// A stored manifest with a key this controller does not know, at the top or inside any block, is read
|
||||
// and its module is left out of every declaration by name; the rest of the catalogue is read; the module
|
||||
// check refuses it. One case per block whose decoder wraps the decoder's words in its own.
|
||||
func TestAStoredManifestWithAnUnknownKeyIsLeftOutAndRegistrationRefusesIt(t *testing.T) {
|
||||
for where, raw := range map[string]string{
|
||||
"the top": `{"module": "later", "version": "2", "a-field-from-later": {"x": 1}}`,
|
||||
"a state": `{"module": "later", "version": "2", "state": [{"name": "s", "a-field-from-later": 1}]}`,
|
||||
"a provided name": `{"module": "later", "version": "2", "provides": [{"name": "p", "a-field-from-later": 1}]}`,
|
||||
"an offer's identity": `{"module": "later", "version": "2", "provides": [{"name": "p", "identity": {"in": "x", "a-field-from-later": 1}}]}`,
|
||||
"a backup": `{"module": "later", "version": "2", "data": {"own": [{"id": "d", "path": "${dir:d}", "class": "valuable", "backup": {"dump": "x", "into": "y", "a-field-from-later": 1}}]}}`,
|
||||
"an own secret": `{"module": "later", "version": "2", "own-secrets": {"s": {"path": "/x", "a-field-from-later": 1}}}`,
|
||||
"a seat's verb": `{"module": "later", "version": "2", "seats": [{"name": "later-seat", "serves": [{"name": "v", "a-field-from-later": 1}]}]}`,
|
||||
} {
|
||||
var m Manifest
|
||||
if err := json.Unmarshal([]byte(raw), &m); err != nil {
|
||||
t.Errorf("%s: the stored manifest was not read: %v", where, err)
|
||||
continue
|
||||
}
|
||||
if m.Module != "later" || m.Version != "2" || !strings.Contains(m.UnknownField(), `"a-field-from-later"`) {
|
||||
t.Errorf("%s: read as %q %q, unknown %q", where, m.Module, m.Version, m.UnknownField())
|
||||
continue
|
||||
}
|
||||
if where != "the top" && !strings.Contains(m.UnknownField(), ": json: unknown field") {
|
||||
t.Errorf("%s: the block's decoder did not say it: %q", where, m.UnknownField())
|
||||
}
|
||||
left := Resolution{Node: "laptop", Modules: []Manifest{m, notifier()}}.LeftOut(nil, false)
|
||||
if why := left["later"]; !strings.Contains(why, "uses a field this controller does not know") ||
|
||||
!strings.Contains(why, "a-field-from-later") {
|
||||
t.Errorf("%s: not left out by name: %v", where, left)
|
||||
}
|
||||
if _, notifierLeft := left["notifier"]; notifierLeft {
|
||||
t.Errorf("%s: another module was left out with it: %v", where, left)
|
||||
}
|
||||
if _, err := ParseManifest([]byte(raw)); err == nil || !strings.Contains(err.Error(), "a-field-from-later") {
|
||||
t.Errorf("%s: the module check took it: %v", where, err)
|
||||
}
|
||||
}
|
||||
var known Manifest
|
||||
if err := json.Unmarshal([]byte(`{"module": "now"}`), &known); err != nil || known.UnknownField() != "" {
|
||||
if err := json.Unmarshal([]byte(`{"module": "now", "state": [{"name": "s"}]}`), &known); err != nil || known.UnknownField() != "" {
|
||||
t.Fatalf("a known manifest: %v %q", err, known.UnknownField())
|
||||
}
|
||||
// A malformed manifest is still refused: only an unknown key is read past.
|
||||
var bad Manifest
|
||||
if err := json.Unmarshal([]byte(`{"module": "bad", "state": [{"name": 3}]}`), &bad); err == nil {
|
||||
t.Fatal("a malformed stored manifest was read")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user