package main import ( "bytes" "os" "path/filepath" "strings" "testing" "time" "github.com/novox/mesh-controller/internal/catalogue" ) // Every catalogue module that runs something long-lived declares how it is ready (novox/hq ADR 0240 rule // 8): `module check` warns and counts the undeclared before the date, and refuses them from it. func TestModuleCheckCountsTheUndeclaredAndRefusesThemFromTheDate(t *testing.T) { dir := t.TempDir() digest := "@sha256:" + strings.Repeat("a", 64) path := filepath.Join(dir, "module.json") os.WriteFile(path, []byte(`{"module":"web","listens":[{"name":"web","port":80,"from":"mesh"}],"resources":[ {"id":"server","type":"container","name":"web","image":"registry.example/web`+digest+`","ports":["80"], "health":{"kind":"http","endpoint":"web"}}, {"id":"worker","type":"container","name":"web-worker","image":"registry.example/web`+digest+`"}, {"id":"seed","type":"container","name":"web-seed","image":"registry.example/web`+digest+`","run-once":true}]}`), 0o600) defer func() { checkNow = time.Now }() checkNow = func() time.Time { return catalogue.HealthRequiredFrom.Add(-time.Hour) } var out bytes.Buffer if err := moduleCheck([]string{path}, &out); err != nil { t.Fatalf("refused before the date: %v\n%s", err, out.String()) } for _, want := range []string{"ready: server by http / on web every 30s", "WARNING: worker stay(s) up", catalogue.HealthRequiredFrom.Format("2006-01-02"), UndeclaredHealthLine + " 1"} { if !strings.Contains(out.String(), want) { t.Errorf("the check does not say %q:\n%s", want, out.String()) } } checkNow = func() time.Time { return catalogue.HealthRequiredFrom } out.Reset() if err := moduleCheck([]string{path}, &out); err == nil { t.Fatalf("a long-running resource without health passed after the date:\n%s", out.String()) } if !strings.Contains(out.String(), "web: worker stays up and does not say how it is ready") { t.Errorf("the refusal does not name the resource:\n%s", out.String()) } }