The watcher hears the self-check's `checked` alone: the consume of mesh-controller.doctor-heartbeat, the subscription to the controller's seat, the follow switch (takeover.go) and its read of mesh-conditions.takeover are gone. The manifest test now lists the one consume and the heartbeat-key test refuses the controller's event. No test added. (issue 774, 774/S11) Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
69 lines
2.2 KiB
Go
69 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// The manifest says what the code does: it consumes the heartbeat and nothing else, calls its own
|
|
// ping and the controller's seats verb, holds no seat (it must not be the controller's), keeps its
|
|
// Telegram token as its own secret, lists its own tools — and names nothing of one installation.
|
|
|
|
func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) {
|
|
raw, err := os.ReadFile(filepath.Join("..", "..", "module.json"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var m struct {
|
|
Module string `json:"module"`
|
|
Consumes []string `json:"consumes"`
|
|
Invokes []string `json:"invokes"`
|
|
Claims []any `json:"claims"`
|
|
Own map[string]string `json:"own-secrets"`
|
|
Tools []string `json:"tools"`
|
|
Build struct {
|
|
Artifacts []map[string]any `json:"artifacts"`
|
|
} `json:"build"`
|
|
}
|
|
if err := json.Unmarshal(raw, &m); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(m.Consumes, []string{"mesh-self-check.checked"}) {
|
|
t.Fatalf("consumes %v", m.Consumes)
|
|
}
|
|
if !reflect.DeepEqual(m.Invokes, []string{m.Module + ".watcher_ping"}) {
|
|
t.Fatalf("invokes %v", m.Invokes)
|
|
}
|
|
if len(m.Claims) != 0 {
|
|
t.Fatalf("a watcher holds no seat: %v", m.Claims)
|
|
}
|
|
env, _ := m.Build.Artifacts[0]["env"].(map[string]any)
|
|
if m.Own["telegram-token"] == "" || env["MESH_WATCHER_TELEGRAM_TOKEN_FILE"] != m.Own["telegram-token"] {
|
|
t.Fatalf("token: own %v, env %v", m.Own, env)
|
|
}
|
|
var served []string
|
|
for _, tool := range tools(NewWatcher(&fakeTelegram{}, time.Now, t.Logf, ""), &listening{}) {
|
|
served = append(served, tool.Name)
|
|
if strings.TrimSpace(tool.Description) == "" {
|
|
t.Errorf("%s has no description", tool.Name)
|
|
}
|
|
}
|
|
listed := append([]string(nil), m.Tools...)
|
|
sort.Strings(served)
|
|
sort.Strings(listed)
|
|
if !reflect.DeepEqual(served, listed) {
|
|
t.Fatalf("serves %v, lists %v", served, listed)
|
|
}
|
|
for _, never := range []string{"/home/", "jochen", "g14", "shanks", "novox", "zurag", "api.telegram"} {
|
|
if strings.Contains(strings.ToLower(string(raw)), never) {
|
|
t.Errorf("module.json names %q", never)
|
|
}
|
|
}
|
|
}
|