package declaration import ( "strings" "testing" ) // A resource's health is held to its kind and bounds on arrival, as the controller holds it near the // author (novox/hq ADR 0240 rule 2): an engine that took a check it could not judge would say a module ready // that nothing looked at. func TestAHealthIsHeldToItsKindAndBounds(t *testing.T) { pinned := "postgres@sha256:" + strings.Repeat("a", 64) parse := func(resource string) error { _, err := Parse([]byte(`{"declaration":1,"resources":[` + resource + `]}`)) return err } container := func(health string, more string) string { return `{"id":"m.db","type":"container","name":"db","image":"` + pinned + `"` + more + `,"health":` + health + `}` } timing := `"interval":"30s","timeout":"5s","looks":3,"grace":"1m0s"` for _, ok := range []string{ container(`{"kind":"http","endpoint":"web","port":31001,"path":"/",`+timing+`}`, ""), container(`{"kind":"exec","command":"pg_isready",`+timing+`}`, ""), container(`{"kind":"runtime",`+timing+`}`, ""), `{"id":"m.d","type":"service","unit":"d.service","state":"running","health":{"kind":"unit",` + timing + `}}`, } { if err := parse(ok); err != nil { t.Errorf("refused %s: %v", ok, err) } } for _, c := range []struct{ resource, says string }{ {container(`{"kind":"http","path":"/",`+timing+`}`, ""), "needs the port"}, {container(`{"kind":"exec",`+timing+`}`, ""), "needs a command"}, {container(`{"kind":"unit",`+timing+`}`, ""), "a service's or a process's own"}, {container(`{"kind":"ping",`+timing+`}`, ""), `of kind "ping"`}, {container(`{"kind":"tcp","port":1,"interval":"5s","timeout":"1s","looks":3,"grace":"0s"}`, ""), "no more often than every 10s"}, {container(`{"kind":"tcp","port":1,"interval":"30s","timeout":"30s","looks":3,"grace":"0s"}`, ""), "less than its interval"}, {container(`{"kind":"tcp","port":1,"interval":"30s","timeout":"5s","looks":1,"grace":"0s"}`, ""), "at least 2 failing looks"}, {container(`{"kind":"tcp","port":1,"interval":"60s","timeout":"5s","looks":3,"grace":"3m"}`, ""), "at most 5m0s"}, {container(`{"kind":"runtime",`+timing+`}`, `,"run-once":true`), "judged on what stays up"}, {`{"id":"m.d","type":"service","unit":"d.service","state":"running","health":{"kind":"runtime",` + timing + `}}`, "a container image's own"}, {container(`{"kind":"tcp","port":1,`+timing+`,"retries":2}`, ""), "retries"}, } { err := parse(c.resource) if err == nil || !strings.Contains(err.Error(), c.says) { t.Errorf("%s: want a refusal saying %q, got %v", c.resource, c.says, err) } } }