Files
llmgw/internal/cli/tui_slurm_test.go
T
Ilker ManapandClaude Opus 5.5 d8ce573bdb
CI / test (push) Failing after 7m1s
Slurm's shared files and users: one path everywhere, accounts as Linux users
slurm.shared mounts the site's NFS export, has an llmgw node export the path
over NFS to the Slurm machines alone (2049 in the firewall), or looks for a
file system the site mounts. slurm.users "llmgw" makes each active account a
Linux user on every Slurm machine: login from its e-mail, a UID from 200000
kept in slurm_users and never reused, its home on the shared path, its SSH
keys from the portal's Profile (or ctl slurm users keys) read by sshd from
/etc/llmgw/ssh-keys. server init --slurm chooses /shared from the first
machine and llmgw's users; --slurm-shared and --slurm-users change that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 21:34:34 +01:00

95 lines
3.4 KiB
Go

package cli
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"
tea "github.com/charmbracelet/bubbletea"
"gitea.mynodes.xyz/ilker/llmgw/internal/config"
"gitea.mynodes.xyz/ilker/llmgw/internal/control/adminapi"
"gitea.mynodes.xyz/ilker/llmgw/internal/control/slurmsvc"
)
func TestTheConsoleLendsANodeToSlurmFromItsRow(t *testing.T) {
var mu sync.Mutex
var put adminapi.SettingsRequest
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/settings":
_ = json.NewEncoder(w).Encode(adminapi.SettingsView{Version: 7,
Body: "slurm:\n enabled: true\n controller: node06\n nodes: [node05, cuda01]\n"})
case r.Method == http.MethodPut && r.URL.Path == "/api/v1/settings":
b, _ := io.ReadAll(r.Body)
mu.Lock()
_ = json.Unmarshal(b, &put)
mu.Unlock()
_ = json.NewEncoder(w).Encode(adminapi.SettingsView{Version: 8})
default:
_, _ = w.Write([]byte("[]"))
}
}))
t.Cleanup(srv.Close)
m := newConsoleModel(srv.URL, "/nonexistent/server.yaml")
m.loaded, m.menu, m.inPanel = true, cSlurm, true
m.data.slurm = slurmsvc.Status{Enabled: true, Cluster: "llmgw", Controller: "node06", Partition: "gpu",
Ctld: &slurmsvc.Reported{SlurmctldRunning: true, SlurmdbdRunning: true, Version: "23.11.4"},
Shared: config.SharedStorage{Path: "/shared", Server: "node06"}, Users: "llmgw", UserCount: 2,
Nodes: []slurmsvc.NodeStatus{
{Node: "node05", Phase: slurmsvc.Lent, Connected: true,
Status: &slurmsvc.Reported{State: "MIXED", Jobs: 2, SlurmdRunning: true, Shared: "mounted"}},
{Node: "cuda01", Phase: slurmsvc.Llmgw, Replicas: 3, Connected: true,
Status: &slurmsvc.Reported{State: "IDLE+DRAIN", SlurmdRunning: true}},
}}
var tm tea.Model = m
view := tm.View()
for _, want := range []string{"slurmctld 23.11.4 and slurmdbd running", "/shared, exported over NFS by node06", "users: 2", "node05", "Slurm's", "MIXED", "cuda01", "llmgw's"} {
if !strings.Contains(view, want) {
t.Errorf("the Slurm view has no %q:\n%s", want, view)
}
}
// cuda01, the second row: lent, after saying its replicas move.
tm = press(tm, "down", "enter")
if !strings.Contains(tm.View(), "Lend to Slurm") {
t.Fatalf("no lend in the menu:\n%s", tm.View())
}
tm = press(tm, "enter")
if !strings.Contains(tm.View(), "3 replica(s) move off first") {
t.Fatalf("the question does not say what moves:\n%s", tm.View())
}
tm = pressRun(tm, "y")
mu.Lock()
defer mu.Unlock()
if put.Base != 7 || !strings.Contains(put.Body, "lent:") || !strings.Contains(put.Body, "cuda01") {
t.Fatalf("the settings put back: %+v", put)
}
if !strings.Contains(tm.View(), "cuda01 is being lent to Slurm") {
t.Errorf("not said:\n%s", tm.View())
}
}
func TestTheConsoleTakesALentNodeBack(t *testing.T) {
m, _ := consoleWith(t, cSlurm)
m.data.slurm = slurmsvc.Status{Enabled: true, Controller: "node06",
Nodes: []slurmsvc.NodeStatus{{Node: "node05", Phase: slurmsvc.Lent, Connected: true}}}
var tm tea.Model = m
tm = press(tm, "enter")
if v := tm.View(); !strings.Contains(v, "Take back from Slurm") || strings.Contains(v, "Lend to Slurm") {
t.Fatalf("a lent node's menu:\n%s", v)
}
}
func TestTheConsoleSaysHowToTurnSlurmOn(t *testing.T) {
m, _ := consoleWith(t, cSlurm)
var tm tea.Model = m
if !strings.Contains(tm.View(), "llmgw ctl slurm setup") {
t.Fatalf("Slurm off says nothing of turning it on:\n%s", tm.View())
}
}