A site whose catalog had no flux-schnell or triposr showed no Images or 3D page, and nothing said they were one click away. The cluster page now has a Pictures and 3D models card under the models: each preset, what it makes, the classes of card here it fits, whether and by whom it was added, and why the leader has not added it by itself; an Add button, which says first when it would install ComfyUI on the GPU nodes and restart the control planes; and the switch for presets.auto. The console's models screen shows the same under its table: A adds one, asking first in the same case, and P turns automatic adding on or off. `ctl model add PRESET` and `ctl model presets` go through the presets API, so the control plane keeps who added one, and `ctl model presets auto on|off` flips the setting; against a control plane from before, add sends the entry as v0.14.4 did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
135 lines
5.5 KiB
Go
135 lines
5.5 KiB
Go
package web
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"log/slog"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/control/adminapi"
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/control/catalog"
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/store"
|
|
)
|
|
|
|
// presetFleet is a cluster whose control plane says its presets: triposr
|
|
// added by itself, flux-schnell removed by somebody.
|
|
type presetFleet struct {
|
|
fakeFleet
|
|
view adminapi.PresetsView
|
|
err error
|
|
added []string
|
|
auto []bool
|
|
}
|
|
|
|
func (f *presetFleet) Presets(context.Context) (adminapi.PresetsView, error) { return f.view, f.err }
|
|
|
|
func (f *presetFleet) AddPreset(_ context.Context, name, by string) error {
|
|
f.added = append(f.added, name+" by "+by)
|
|
return nil
|
|
}
|
|
|
|
func (f *presetFleet) SetAutoPresets(_ context.Context, on bool, _ string) error {
|
|
f.auto = append(f.auto, on)
|
|
return nil
|
|
}
|
|
|
|
func newPresetFleet() *presetFleet {
|
|
no := false
|
|
return &presetFleet{view: adminapi.PresetsView{Auto: true, Presets: []adminapi.PresetView{
|
|
{Name: "flux-schnell", Makes: "pictures", Card: "cc 7.0+, 24 GB+", Licence: catalog.License{Name: "Apache-2.0"},
|
|
FitsClasses: []string{"v100-32g"}, Fits: true, Declined: true,
|
|
Blocked: "removed from the catalog after it was added; add it again to undo"},
|
|
{Name: "sdxl", Makes: "pictures", Card: "cc 8.0+", Licence: catalog.License{Name: "x"},
|
|
Blocked: "the cluster installs no ComfyUI (engines.comfyui); adding it by hand sets that"},
|
|
{Name: "triposr", Makes: "meshes", Card: "cc 7.0+, 8 GB+", Licence: catalog.License{Name: "Made-up", Commercial: &no},
|
|
FitsClasses: []string{"t4-15g", "v100-32g"}, Fits: true, InCatalog: true, AddedBy: "auto",
|
|
AddedAt: time.Date(2026, 10, 13, 9, 30, 0, 0, time.UTC)},
|
|
}}}
|
|
}
|
|
|
|
func TestThePicturesAnd3DModelsAreAddedFromTheClusterPage(t *testing.T) {
|
|
a := fakeAccounts{user: store.User{ID: "u1", Email: "a@example.com", IsAdmin: true}}
|
|
p := NewAccountPages(a, nil, nil, "v0", slog.New(slog.NewTextHandler(io.Discard, nil)))
|
|
f := newPresetFleet()
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("GET /admin", p.AdminPage(Dashboard(f, nil, "v1", time.Second, false, NavExtras{}, nil)))
|
|
p.RegisterPresets(mux, f)
|
|
|
|
body := mirrorGet(t, mux, "/admin").Body.String()
|
|
for _, want := range []string{
|
|
`id="presets"`, "Pictures and 3D models",
|
|
`action="/admin/presets/flux-schnell"`, "Add again", "removed, so not added again by itself",
|
|
"added automatically, 2026-10-13 09:30", "Made-up, not for commercial use", "t4-15g, v100-32g",
|
|
`action="/admin/presets/auto"`, `name="on" value="false"`, "Stop adding them",
|
|
"(the cluster installs no ComfyUI (engines.comfyui); adding it by hand sets that)",
|
|
"restarts the control planes",
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("%q not on the page", want)
|
|
}
|
|
}
|
|
// The button's title and the line beside it, on each preset not here:
|
|
// the cluster installs no ComfyUI yet.
|
|
if n := strings.Count(body, "restarts the control planes"); n != 4 {
|
|
t.Errorf("the ComfyUI warning is said %d times, not on the two presets an Add would install it for", n)
|
|
}
|
|
if strings.Contains(body, "(removed from the catalog") {
|
|
t.Error("a decline is said twice")
|
|
}
|
|
if strings.Contains(body, `action="/admin/presets/triposr"`) {
|
|
t.Error("a preset in the catalog is offered to be added")
|
|
}
|
|
|
|
w := mirrorPost(t, mux, "/admin/presets/flux-schnell", url.Values{"csrf": {"tok"}})
|
|
if w.Code != http.StatusSeeOther || len(f.added) != 1 || f.added[0] != "flux-schnell by a@example.com" {
|
|
t.Fatalf("status %d, added %v", w.Code, f.added)
|
|
}
|
|
if loc := w.Header().Get("Location"); !strings.Contains(loc, "notice=") || !strings.HasSuffix(loc, "#presets") {
|
|
t.Errorf("redirected to %s", loc)
|
|
}
|
|
w = mirrorPost(t, mux, "/admin/presets/auto", url.Values{"csrf": {"tok"}, "on": {"false"}})
|
|
if w.Code != http.StatusSeeOther || len(f.auto) != 1 || f.auto[0] || len(f.added) != 1 {
|
|
t.Fatalf("status %d, auto %v, added %v: auto was taken for a preset's name", w.Code, f.auto, f.added)
|
|
}
|
|
if w := mirrorPost(t, mux, "/admin/presets/triposr", url.Values{"csrf": {"bad"}}); w.Code != http.StatusBadRequest || len(f.added) != 1 {
|
|
t.Errorf("a forged form was accepted: %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestNoComfyUIWarningWhereTheClusterInstallsIt(t *testing.T) {
|
|
f := newPresetFleet()
|
|
f.view.ComfyUI = "0.39.2"
|
|
a := fakeAccounts{user: store.User{ID: "u1", Email: "a@example.com", IsAdmin: true}}
|
|
p := NewAccountPages(a, nil, nil, "v0", slog.New(slog.NewTextHandler(io.Discard, nil)))
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("GET /admin", p.AdminPage(Dashboard(f, nil, "v1", time.Second, false, NavExtras{}, nil)))
|
|
body := mirrorGet(t, mux, "/admin").Body.String()
|
|
if !strings.Contains(body, `action="/admin/presets/flux-schnell"`) {
|
|
t.Fatal("no Add on the page")
|
|
}
|
|
if strings.Contains(body, "restarts the control planes") {
|
|
t.Error("warned of installing a ComfyUI the cluster already installs")
|
|
}
|
|
}
|
|
|
|
func TestThePresetsCardIsLeftOffWhereTheControlPlaneCannotSay(t *testing.T) {
|
|
f := newPresetFleet()
|
|
f.err = errors.New("501")
|
|
_, body := get(t, Dashboard(f, nil, "v1", time.Second, true, NavExtras{}, nil), "http://127.0.0.1:9090/", nil)
|
|
if strings.Contains(body, `id="presets"`) {
|
|
t.Error("an empty presets card was drawn")
|
|
}
|
|
// The read-only page shows them, with nothing to press.
|
|
f.err = nil
|
|
_, body = get(t, Dashboard(f, nil, "v1", time.Second, true, NavExtras{}, nil), "http://127.0.0.1:9090/", nil)
|
|
if !strings.Contains(body, `id="presets"`) || strings.Contains(body, `/admin/presets/`) {
|
|
t.Errorf("the admin listener's page: card %v, forms %v",
|
|
strings.Contains(body, `id="presets"`), strings.Contains(body, `/admin/presets/`))
|
|
}
|
|
}
|