Clicking a repository in the explorer shows its card and files in a row beneath it, fetched from /admin/mirror/repo, and a second click closes it; the list stays where it was. The link still leads to the repository's own page without script or with a modifier key. A repository's files now take one line each, and an importance matrix published beside the quantisations is marked as not a model rather than offered for fetching. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
166 lines
6.6 KiB
Go
166 lines
6.6 KiB
Go
package web
|
|
|
|
import (
|
|
"errors"
|
|
"html"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/hf"
|
|
)
|
|
|
|
func ggufModel(id, arch string, params int64, created time.Time) hf.Model {
|
|
return hf.Model{ID: id, CreatedAt: created, LastModified: created,
|
|
GGUF: &hf.GGUFInfo{Total: params, Architecture: arch, ContextLength: 32768}}
|
|
}
|
|
|
|
func TestTheExplorerOpensOnTrendingModelsTheNodesCanRun(t *testing.T) {
|
|
// Opened from the menu, with nothing typed: what is current, in the
|
|
// shape this cluster runs, without a search to start it.
|
|
now := time.Now()
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("Qwen/Qwen3-8B-GGUF", "qwen3", 8.2e9, now.Add(-90*24*time.Hour)),
|
|
ggufModel("odd/Kev-GGUF", "ggmlc", 5e8, now.Add(-2*24*time.Hour)),
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror").Body.String()
|
|
|
|
q := reg.query
|
|
if q.Sort != hf.SortTrending || q.Task != "text-generation" || !q.GGUF || q.Search != "" {
|
|
t.Errorf("asked the registry for %+v", q)
|
|
}
|
|
if !strings.Contains(body, "Qwen/Qwen3-8B-GGUF") || !strings.Contains(body, "8.2B") {
|
|
t.Errorf("the trending model is missing or unsized: %s", body)
|
|
}
|
|
// The kev case: listed, it invites a fetch the nodes cannot use.
|
|
if strings.Contains(body, "odd/Kev-GGUF") {
|
|
t.Error("a model llama.cpp cannot load is offered")
|
|
}
|
|
if !strings.Contains(body, "1 more is hidden") {
|
|
t.Error("the page should say something was hidden, and why")
|
|
}
|
|
}
|
|
|
|
func TestUntickingRunsHereShowsEverythingWithAVerdict(t *testing.T) {
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("odd/Kev-GGUF", "ggmlc", 5e8, time.Now()),
|
|
}}
|
|
// x=1 is the submitted form; "here" absent is the box unticked.
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror?x=1&view=downloads&task=any&size=9").Body.String()
|
|
|
|
q := reg.query
|
|
if q.GGUF || q.Sort != hf.SortDownloads || q.Task != "" || q.MaxParams != 9e9 {
|
|
t.Errorf("asked the registry for %+v", q)
|
|
}
|
|
if !strings.Contains(body, "odd/Kev-GGUF") || !strings.Contains(body, "ggmlc ✗") {
|
|
t.Errorf("the unrunnable model should be listed and marked: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestNewThisMonthLeavesOutOlderRepositories(t *testing.T) {
|
|
now := time.Now()
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("a/Old-GGUF", "llama", 1e9, now.Add(-200*24*time.Hour)),
|
|
ggufModel("a/Fresh-GGUF", "llama", 1e9, now.Add(-3*24*time.Hour)),
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror?view=new").Body.String()
|
|
if strings.Contains(body, "a/Old-GGUF") || !strings.Contains(body, "a/Fresh-GGUF") {
|
|
t.Errorf("new this month shows the wrong repositories: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestOpeningARepositoryKeepsTheWayBack(t *testing.T) {
|
|
reg := &fakeRegistry{results: []hf.Model{ggufModel("a/B-GGUF", "llama", 1e9, time.Now())}}
|
|
mux := mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg})
|
|
body := html.UnescapeString(mirrorGet(t, mux, "/admin/mirror?view=new&size=3").Body.String())
|
|
if !strings.Contains(body, "size=3") || !strings.Contains(body, "repo=a%2FB-GGUF") {
|
|
t.Fatalf("the row's link should keep the filters: %s", body)
|
|
}
|
|
|
|
reg.repo = hf.Repo{ID: "a/B-GGUF", Revision: "abc123def456"}
|
|
body = html.UnescapeString(mirrorGet(t, mux, "/admin/mirror?view=new&size=3&repo=a/B-GGUF").Body.String())
|
|
if !strings.Contains(body, "back to the list") || !strings.Contains(body, "view=new") {
|
|
t.Errorf("the repository page should lead back to the same listing: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestAnAdapterIsNotListedAsAModel(t *testing.T) {
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("a/Some-LoRA-GGUF", "qwen2", 2e6, time.Now()),
|
|
ggufModel("a/Tiny-GGUF", "qwen2", 135e6, time.Now()),
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror").Body.String()
|
|
if strings.Contains(body, "Some-LoRA") || !strings.Contains(body, "a/Tiny-GGUF") {
|
|
t.Errorf("adapters should be left out and small models kept: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestARepositoryShowsItsCard(t *testing.T) {
|
|
reg := &fakeRegistry{repo: hf.Repo{
|
|
ID: "Qwen/X-GGUF", Revision: "abc123def456", License: "apache-2.0",
|
|
BaseModel: []string{"Qwen/X"}, Card: "# X\n\nA **small** model. See [the license](LICENSE).",
|
|
Files: []hf.File{{Path: "x.gguf", Bytes: 10}},
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror?repo=Qwen/X-GGUF").Body.String()
|
|
for _, want := range []string{"<strong>small</strong>", "license apache-2.0", "<code>Qwen/X</code>",
|
|
`href="https://huggingface.co/Qwen/X-GGUF/blob/abc123def456/LICENSE"`,
|
|
`href="https://huggingface.co/Qwen/X-GGUF"`} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("missing %s", want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestARepositoryOpensAsAFragmentBeneathItsRow(t *testing.T) {
|
|
reg := &fakeRegistry{repo: hf.Repo{
|
|
ID: "Qwen/X-GGUF", Revision: "abc123def456", Card: "A **small** model.",
|
|
Files: []hf.File{{Path: "x.gguf", Bytes: 10}},
|
|
}}
|
|
rec := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror/repo?repo=Qwen/X-GGUF")
|
|
body := rec.Body.String()
|
|
if rec.Code != 200 {
|
|
t.Fatalf("status %d: %s", rec.Code, body)
|
|
}
|
|
// The card and the fetch form, and not a page around them.
|
|
for _, want := range []string{"<strong>small</strong>", `action="/admin/mirror/fetch"`, `name="csrf"`} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("missing %s: %s", want, body)
|
|
}
|
|
}
|
|
for _, unwanted := range []string{"<html", "back to the list", "<h3>"} {
|
|
if strings.Contains(body, unwanted) {
|
|
t.Errorf("the fragment carries %s", unwanted)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAFragmentForARegistryThatFailsSaysSo(t *testing.T) {
|
|
reg := &fakeRegistry{err: errors.New("reaching the model registry: timeout")}
|
|
rec := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror/repo?repo=Qwen/X-GGUF")
|
|
if rec.Code != 502 || !strings.Contains(rec.Body.String(), "timeout") {
|
|
t.Errorf("status %d: %s", rec.Code, rec.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestAnImportanceMatrixIsNotOfferedAsAModel(t *testing.T) {
|
|
reg := &fakeRegistry{repo: hf.Repo{
|
|
ID: "a/X-GGUF", Revision: "abc123def456", Architecture: "qwen2",
|
|
Files: []hf.File{{Path: "x-q4_k_m.gguf", Bytes: 10}, {Path: "imatrix-x.gguf", Bytes: 5}},
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror/repo?repo=a/X-GGUF").Body.String()
|
|
if !strings.Contains(body, "importance matrix") {
|
|
t.Errorf("the imatrix should be marked as not a model: %s", body)
|
|
}
|
|
if strings.Count(body, `action="/admin/mirror/fetch"`) != 1 {
|
|
t.Errorf("only the model should have a fetch form: %s", body)
|
|
}
|
|
}
|