Files
mesh-delivery/modules/mesh-delivery-view/internal/view/backlog_test.go
T
jschoubben 0de534c692 Names N3 (view): the status view names its own buckets from its credential's module
Its states answers, reach and waits (viewstate WaitsBucket, ReachBucket, ViewAnswersBucket), its
first views and its marks were named from the constant ViewModule; they are now
`<cred.Module>_<state>` (viewstate.BucketsOf), and the model is made for its module.

Builds: design 47 G A-296

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 19:14:55 +01:00

96 lines
3.3 KiB
Go

package view
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-view/viewstate"
"github.com/nats-io/nats.go/jetstream"
)
func stepAsk(t *testing.T, id, kind string, at time.Time) []byte {
t.Helper()
b, err := buildstep.EncodeStepAsk(buildstep.StepAsk{ID: id, Kind: kind, Language: buildstep.AskGo, Asker: "mesh-delivery-checker", At: at,
Check: &buildstep.CheckJob{Fetch: buildstep.Fetch{Repository: "novox/x", Commit: "0123456789abcdef0123456789abcdef01234567"}, Levels: []string{buildstep.LevelUnit}}})
if err != nil {
t.Fatal(err)
}
return b
}
// fakeSeats is the check worker of the go seat with three asks waiting and one held, the oldest at t0.
func fakeSeats(t *testing.T, now time.Time) *Backlog {
worker, _ := buildstep.AskWorker(buildstep.AskGo, buildstep.AskCheck)
subject, _ := buildstep.AskSubject(buildstep.AskGo, buildstep.AskCheck)
oldest := stepAsk(t, "m0000001aaaaaa", buildstep.AskCheck, now.Add(-90*time.Second))
return &Backlog{Now: func() time.Time { return now },
Info: func(stream, w string) (uint64, uint64, uint64, error) {
switch w {
case worker:
return 3, 1, 42, nil
case "SEAT_NODE_BUILD_IMAGE_DELIVERY_worker":
return 0, 0, 1, fmt.Errorf("the worker is not there")
}
return 0, 0, 1, nil
},
Message: func(stream, s string, seq uint64) ([]byte, error) {
if seq != 42 {
return nil, fmt.Errorf("asked %s at %d", s, seq)
}
switch s {
case subject: // main's form holds a younger ask
return stepAsk(t, "m0000002bbbbbb", buildstep.AskCheck, now.Add(-30*time.Second)), nil
case subject + ".*": // the asker's form holds the oldest
return oldest, nil
}
return nil, jetstream.ErrMsgNotFound
}}
}
func TestThreeWaitingAsksAreShownWithTheOldestsAge(t *testing.T) { // 1887/A8a AC
now := time.Date(2026, 10, 23, 12, 0, 0, 0, time.UTC)
m := New(viewstate.ViewModule)
m.SetBacklog(fakeSeats(t, now))
rows := m.Snapshot().Backlog
var check, image *BacklogRow
for i := range rows {
switch {
case rows[i].Language == "go" && rows[i].Kind == "check":
check = &rows[i]
case rows[i].Language == "image" && rows[i].Kind == "delivery":
image = &rows[i]
default:
t.Errorf("a quiet seat is listed: %+v", rows[i])
}
}
if check == nil || check.Waiting != 3 || check.Held != 1 || check.OldestSecs != 90 || !check.Oldest.Equal(now.Add(-90*time.Second)) || check.Error != "" {
t.Fatalf("check row = %+v", check)
}
if image == nil || image.Error == "" {
t.Errorf("a worker that cannot be read is dropped: %+v", rows)
}
var out strings.Builder
Table(&out, m.Snapshot())
for _, w := range []string{"BACKLOG OF BUILD ASKS", "go", "check", "3", "1m30s", "unreadable"} {
if !strings.Contains(out.String(), w) {
t.Errorf("table lacks %q:\n%s", w, out.String())
}
}
rec := httptest.NewRecorder()
Web(m).ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
if !strings.Contains(rec.Body.String(), "BACKLOG OF BUILD ASKS") || !strings.Contains(rec.Body.String(), "1m30s") {
t.Errorf("page lacks the backlog:\n%s", rec.Body.String())
}
}
func TestNoBacklogReaderGivesNoRows(t *testing.T) {
if got := New(viewstate.ViewModule).Snapshot().Backlog; got == nil || len(got) != 0 {
t.Errorf("backlog = %#v", got)
}
}