// Coverage for the flyto.HealthChecker capability + its transcription // pre-flight wiring. flyto.HealthChecker 能力 + 转写前探活接线的覆盖. package openai import ( "context" "net/http" "net/http/httptest" "strings" "testing" "git.flytoex.net/yuanwei/flyto-agent/core/pkg/flyto" ) func TestCheckHealth(t *testing.T) { t.Run("no path configured -> no-op nil", func(t *testing.T) { p := New(Config{APIKey: "k", BaseURL: "http://unreachable.invalid"}) if err := p.CheckHealth(context.Background()); err != nil { t.Fatalf("want nil (no probe available != unhealthy), got %v", err) } }) t.Run("healthy 200", func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/health" { t.Errorf("probe path = %q", r.URL.Path) } if r.Header.Get("Authorization") != "" { t.Error("health probe must be unauthenticated") } _, _ = w.Write([]byte(`{"status":"healthy","engine_pool":{"model_count":33}}`)) })) defer srv.Close() p := New(Config{APIKey: "k", BaseURL: srv.URL, HealthCheckPath: "/health"}) if err := p.CheckHealth(context.Background()); err != nil { t.Fatalf("want healthy, got %v", err) } }) t.Run("ok 200 (multi-backend router shape)", func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(`{"status":"ok","backends":{"m5max":{"healthy":true}}}`)) })) defer srv.Close() p := New(Config{APIKey: "k", BaseURL: srv.URL, HealthCheckPath: "/health"}) if err := p.CheckHealth(context.Background()); err != nil { t.Fatalf("want healthy (router reports ok), got %v", err) } }) t.Run("200 but status not healthy -> error", func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(`{"status":"degraded"}`)) })) defer srv.Close() p := New(Config{APIKey: "k", BaseURL: srv.URL, HealthCheckPath: "/health"}) if err := p.CheckHealth(context.Background()); err == nil || !strings.Contains(err.Error(), "degraded") { t.Fatalf("want degraded error, got %v", err) } }) t.Run("unreachable backend -> offline error", func(t *testing.T) { p := New(Config{APIKey: "k", BaseURL: "http://127.0.0.1:1", HealthCheckPath: "/health"}) if err := p.CheckHealth(context.Background()); err == nil { t.Fatal("want offline error") } }) } func TestTranscribe_PreflightBlocksUpload(t *testing.T) { uploaded := false srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/health" { http.Error(w, `{"status":"down"}`, http.StatusServiceUnavailable) return } uploaded = true _, _ = w.Write([]byte(`{"text":"x"}`)) })) defer srv.Close() p := New(Config{APIKey: "k", BaseURL: srv.URL, HealthCheckPath: "/health"}) _, err := p.Transcribe(context.Background(), &flyto.TranscriptionRequest{ Audio: strings.NewReader("big"), Model: "m", }) if err == nil || !strings.Contains(err.Error(), "pre-flight") { t.Fatalf("want pre-flight failure, got %v", err) } if uploaded { t.Error("audio must not be uploaded when the pre-flight fails") } }