package health_test import ( "context" "fmt" "net/http" "net/http/httptest" "testing" "time" "git.wntrmute.dev/kyle/crossbar/internal/health" ) // propsFake answers /health, /v1/models and a configurable /props. func propsFake(t *testing.T, props string, status int) *httptest.Server { mux := http.NewServeMux() mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, `{"status":"ok"}`) }) mux.HandleFunc("/v1/models", func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, `{"data":[{"id":"m"}]}`) }) mux.HandleFunc("/props", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(status) fmt.Fprint(w, props) }) srv := httptest.NewServer(mux) t.Cleanup(srv.Close) return srv } func TestPropsLearned(t *testing.T) { srv := propsFake(t, `{"default_generation_settings":{"n_ctx":131072,"params":{}},"total_slots":4,"model_path":"/x/m.gguf","chat_template":"..."}`, 200) tbl := health.New(map[string]string{"a": srv.URL}, time.Hour, nil) tbl.PollOnce(context.Background()) s, _ := tbl.Get("a") if !s.Healthy || s.NCtx != 131072 || s.Slots != 4 { t.Fatalf("status = %+v, want healthy with NCtx 131072 and Slots 4", s) } if got := s.PerSlotCtx(); got != 32768 { t.Errorf("PerSlotCtx = %d, want 131072/4", got) } } func TestPropsAbsentOrBrokenIsNotAFailure(t *testing.T) { for name, tc := range map[string]struct { props string status int }{ "404": {`not found`, 404}, "not json": {``, 200}, "no fields": {`{"model_path":"/x"}`, 200}, "zero ctx": {`{"default_generation_settings":{"n_ctx":0},"total_slots":0}`, 200}, } { t.Run(name, func(t *testing.T) { srv := propsFake(t, tc.props, tc.status) tbl := health.New(map[string]string{"a": srv.URL}, time.Hour, nil) tbl.PollOnce(context.Background()) s, _ := tbl.Get("a") if !s.Healthy { t.Fatalf("a bad /props must not make the host unhealthy: %+v", s) } if s.NCtx != 0 || s.Slots != 0 || s.PerSlotCtx() != 0 { t.Errorf("unknown context must read as 0: %+v", s) } }) } } func TestPerSlotCtxWithUnknownSlots(t *testing.T) { s := health.Status{NCtx: 8192, Slots: 0} if s.PerSlotCtx() != 8192 { t.Errorf("with Slots unknown the whole context is the per-slot value; got %d", s.PerSlotCtx()) } s = health.Status{NCtx: 8192, Slots: 3} if s.PerSlotCtx() != 2730 { t.Errorf("integer division: got %d, want 2730", s.PerSlotCtx()) } }