Files
llmgw/internal/web/install_test.go
T
Ilker ManapandClaude Opus 5.5 fea5774fe5 The install guide shows every screen of a real install
/install takes a reader from three bare Ubuntu machines to a first answer:
what each machine needs and the commands that check it, the release fetched
and its checksum checked, the eight setup screens, the system's state and
the console, and a first request with a key from the account page. Every
screen is from an install of v0.14.9 on three fresh VMs, recorded with tmux
and kept as terminal frames: the page shows them as text, and plays a
session back when asked, fetching it compressed from /install/cast/. The
administrator's password and the API key were masked before the recording
was kept, and a test fails if either shape reaches the page.

/about gains what llmgw now does beyond routing, and its install steps are
today's: the setup screens and node add, not onboard-node.sh and a model
file, with a link into the guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 01:35:08 +02:00

107 lines
3.4 KiB
Go

package web
import (
"bytes"
"net/http"
"net/http/httptest"
"regexp"
"strings"
"testing"
)
func TestInstallGuideShowsEveryStepAndRecording(t *testing.T) {
code, body := get(t, Install("v1.2.3"), "http://llmgw.example/install", nil)
if code != http.StatusOK {
t.Fatalf("status %d", code)
}
for _, want := range []string{
"<!doctype html>",
`id="before"`, `id="binary"`, `id="setup"`, `id="check"`, `id="use"`, `id="trouble"`,
"sha256sum -c --ignore-missing",
"sudo llmgw server init",
`href="/about"`,
"/_static/guide/admin.png?v=",
// The recording's own screens, not a description of them.
"High availability", "All three are ready.", "The control plane is up",
} {
if !strings.Contains(body, want) {
t.Errorf("the guide does not have %q", want)
}
}
if n := strings.Count(body, `class="tty" data-src="/install/cast/`); n != len(guide.Casts) {
t.Errorf("%d players on the page, %d recordings", n, len(guide.Casts))
}
}
// The recording was of a real install, with a real administrator's password
// and a real key on screen. Neither may reach the page.
func TestInstallGuideCarriesNoSecret(t *testing.T) {
_, body := get(t, Install("v1.2.3"), "http://llmgw.example/install", nil)
for _, rx := range []*regexp.Regexp{
regexp.MustCompile(`sk-llmgw-[A-Za-z0-9_-]{8,}`),
regexp.MustCompile(`password(\s|<[^>]*>)+[a-z0-9]{16,}`),
} {
if m := rx.FindString(body); m != "" {
t.Errorf("the guide shows %q", m)
}
}
}
func TestEveryGuideStepHasItsScreen(t *testing.T) {
for _, name := range []string{"setup-start", "setup-choices", "setup-admin", "setup-machines",
"setup-checks", "setup-plan", "setup-install", "setup-done"} {
s, ok := guide.Stills[name]
if !ok || len(s.Lines) == 0 {
t.Errorf("no screen %s", name)
continue
}
if _, ok := guide.Casts[s.Cast]; !ok {
t.Errorf("screen %s is of a recording, %s, the guide does not have", name, s.Cast)
}
}
}
func TestInstallGuideAsTheWebsite(t *testing.T) {
d := NewInstallData("v1.2.3")
d.Site = true
var b bytes.Buffer
if err := RenderInstall(&b, d); err != nil {
t.Fatal(err)
}
body := b.String()
for _, not := range []string{"<!doctype", "</body>", "/_static/", `href="/about"`} {
if strings.Contains(body, not) {
t.Errorf("the website's guide has %q", not)
}
}
if !strings.Contains(body, `src="guide/admin.png"`) {
t.Error("the website's guide does not take its pictures from beside it")
}
}
func TestTheRecordingsAreServedCompressed(t *testing.T) {
r := httptest.NewRequest("GET", "http://llmgw.example/install/cast/2-setup.json", nil)
r.SetPathValue("file", "2-setup.json")
r.Header.Set("Accept-Encoding", "gzip, br")
w := httptest.NewRecorder()
InstallCast(w, r)
if w.Code != http.StatusOK || w.Header().Get("Content-Encoding") != "gzip" {
t.Fatalf("%d %v", w.Code, w.Header())
}
// And plain to a client that does not take gzip.
r = httptest.NewRequest("GET", "http://llmgw.example/install/cast/2-setup.json", nil)
r.SetPathValue("file", "2-setup.json")
w = httptest.NewRecorder()
InstallCast(w, r)
if !strings.HasPrefix(w.Body.String(), `{"rows":`) {
t.Errorf("plain body starts %.20q", w.Body.String())
}
r = httptest.NewRequest("GET", "http://llmgw.example/install/cast/nothing.json", nil)
r.SetPathValue("file", "nothing.json")
w = httptest.NewRecorder()
InstallCast(w, r)
if w.Code != http.StatusNotFound {
t.Errorf("an unknown recording answered %d", w.Code)
}
}