The console gains live views of nodes, GPUs, models, replicas, usage and agent logs, and a settings tree over every key of server.yaml (agent.yaml on a node), generated from the configuration structs: values with their defaults and doc comments, edited in dialogs, saved only once the service's own loader accepts them, comments kept. The generator now tells blocks apart by package, which brings the TLS, engine and supervisor settings back into the reference. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
123 lines
3.5 KiB
Go
123 lines
3.5 KiB
Go
package settings
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/config"
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/docgen"
|
|
)
|
|
|
|
func TestEveryKeyOfBothFilesCanBeReached(t *testing.T) {
|
|
// Walked from each file's root: every block a key opens is found, so no
|
|
// setting is a dead end on the screens.
|
|
for _, file := range []string{"/etc/llmgw/server.yaml", "/etc/llmgw/agent.yaml"} {
|
|
root, err := Root(file)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
seen := map[string]bool{}
|
|
var walk func(b *docgen.Block, path string)
|
|
count := 0
|
|
walk = func(b *docgen.Block, path string) {
|
|
if seen[b.ID()] {
|
|
return
|
|
}
|
|
seen[b.ID()] = true
|
|
for _, k := range Keys(b) {
|
|
count++
|
|
if k.Nested != "" && k.Block == nil {
|
|
t.Errorf("%s: %s.%s opens %s, which is not in the reference", file, path, k.Key, k.Nested)
|
|
}
|
|
if k.Block != nil {
|
|
walk(k.Block, path+"."+k.Key)
|
|
}
|
|
}
|
|
}
|
|
walk(root, "")
|
|
if count < 20 {
|
|
t.Errorf("%s: only %d keys reached", file, count)
|
|
}
|
|
}
|
|
// The TLS settings, which the reference used to lose to a name clash.
|
|
root, _ := Root("server.yaml")
|
|
for _, k := range Keys(root) {
|
|
if k.Key == "agent_tls" && (k.Kind != Block || k.Block.ID() != "tlsconf.Config") {
|
|
t.Errorf("agent_tls is %v %v", k.Kind, k.Block)
|
|
}
|
|
if k.Key == "endpoints" && k.Kind != BlockList {
|
|
t.Errorf("endpoints is %v", k.Kind)
|
|
}
|
|
}
|
|
}
|
|
|
|
const sample = `# The control plane.
|
|
listen: ":8080"
|
|
router:
|
|
# How many other endpoints to try.
|
|
retries: 2
|
|
`
|
|
|
|
func TestAnEditKeepsTheFilesCommentsAndIsCheckedBeforeItIsWritten(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "server.yaml")
|
|
if err := os.WriteFile(path, []byte(sample), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
d, err := Open(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := d.Set([]string{"router", "retries"}, Int, "three"); err == nil {
|
|
t.Error("a word was taken for a number")
|
|
}
|
|
if err := d.Set([]string{"router", "retries"}, Int, "3"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := d.Set([]string{"router", "cooldown"}, Duration, "45s"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
check := func(p string) error { _, err := config.Load(p); return err }
|
|
if _, err := d.Save(check); err != nil {
|
|
t.Fatalf("a good edit was refused: %v", err)
|
|
}
|
|
b, _ := os.ReadFile(path)
|
|
for _, want := range []string{"# The control plane.", "# How many other endpoints to try.", "retries: 3", "cooldown: 45s"} {
|
|
if !strings.Contains(string(b), want) {
|
|
t.Errorf("the file lacks %q:\n%s", want, b)
|
|
}
|
|
}
|
|
|
|
// Two endpoints with one id: the loader refuses, and nothing is written.
|
|
for range 2 {
|
|
i := d.Append([]string{"endpoints"})
|
|
for _, kv := range [][2]string{{"id", "a"}, {"url", "http://x"}} {
|
|
if err := d.Set([]string{"endpoints", itoa(i), kv[0]}, Text, kv[1]); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
_ = d.Set([]string{"endpoints", itoa(i), "models"}, TextList, "m")
|
|
}
|
|
if _, err := d.Save(check); err == nil {
|
|
t.Error("an invalid configuration was saved")
|
|
}
|
|
if b2, _ := os.ReadFile(path); string(b2) != string(b) {
|
|
t.Error("a refused save changed the file")
|
|
}
|
|
}
|
|
|
|
func TestTheValueThatAppliesIsShownWhenTheFileSetsNone(t *testing.T) {
|
|
cfg := config.Default()
|
|
if v, ok := Effective(cfg, []string{"router", "retries"}); !ok || v != "2" {
|
|
t.Errorf("router.retries: %q %v", v, ok)
|
|
}
|
|
if v, ok := Effective(cfg, []string{"router", "cooldown"}); !ok || v != "15s" {
|
|
t.Errorf("router.cooldown: %q", v)
|
|
}
|
|
}
|
|
|
|
func itoa(i int) string { return strconv.Itoa(i) }
|