feat: use Halvo78 playground as primary default endpoint with automatic failover
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestChatMessageGetContentString(t *testing.T) {
|
||||
@@ -652,5 +653,95 @@ func TestResolveMaxTokens(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestQwenServiceSandboxFailover(t *testing.T) {
|
||||
server1Hits := 0
|
||||
server2Hits := 0
|
||||
|
||||
// Server 1: Returns Gradio chat_response sandbox simulation
|
||||
server1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
server1Hits++
|
||||
if r.URL.Path == "/gradio_api/call/chat_response" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"event_id": "sandbox_event"}`))
|
||||
return
|
||||
}
|
||||
if r.URL.Path == "/gradio_api/call/chat_response/sandbox_event" {
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
flusher, _ := w.(http.Flusher)
|
||||
chunk := "event: complete\n" +
|
||||
"data: [[{\"role\": \"user\", \"content\": [{\"text\": \"hello\", \"type\": \"text\"}]}, {\"role\": \"assistant\", \"content\": [{\"text\": \"> 💭 **Thinking Process (QSA Micro-block Reasoning):**\\n\\n### Qwen3.8-Flash-Next Sandbox Response\\n\\nTo connect to a live inference engine, enter your endpoint credentials.\", \"type\": \"text\"}]}]]\n\n"
|
||||
w.Write([]byte(chunk))
|
||||
flusher.Flush()
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
}))
|
||||
defer server1.Close()
|
||||
|
||||
// Server 2: Standard OpenAI server returning live completion
|
||||
server2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
server2Hits++
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"choices":[{"message":{"role":"assistant","content":"Live completion from fallback server"},"finish_reason":"stop"}]}`))
|
||||
}))
|
||||
defer server2.Close()
|
||||
|
||||
svc := NewQwenService([]string{server1.URL, server2.URL}, "Qwen/Qwen3.8-Flash-Next", "auto", "", "", "", "", true, true)
|
||||
// Explicitly assign modes for mock URLs
|
||||
svc.endpoints[0].Mode = "chat_response"
|
||||
svc.endpoints[1].Mode = "openai"
|
||||
|
||||
// 1. Non-streaming failover test
|
||||
rec := httptest.NewRecorder()
|
||||
req := ChatCompletionRequest{
|
||||
Model: "qwen",
|
||||
Messages: []ChatMessage{{Role: "user", Content: "hello"}},
|
||||
Stream: false,
|
||||
}
|
||||
|
||||
err := svc.Chat(rec, nil, req)
|
||||
if err != nil {
|
||||
t.Fatalf("expected failover to succeed, got error: %v", err)
|
||||
}
|
||||
|
||||
var res ChatCompletionResponse
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &res); err != nil {
|
||||
t.Fatalf("failed to decode response: %v", err)
|
||||
}
|
||||
if res.Choices[0].Message.Content != "Live completion from fallback server" {
|
||||
t.Fatalf("unexpected content from failover: %v", res.Choices[0].Message.Content)
|
||||
}
|
||||
if server1Hits != 2 { // 1 for /gradio_api/call, 1 for /gradio_api/call/sandbox_event
|
||||
t.Fatalf("expected server1 to be attempted, got %d hits", server1Hits)
|
||||
}
|
||||
if server2Hits != 1 {
|
||||
t.Fatalf("expected server2 to be reached on failover, got %d hits", server2Hits)
|
||||
}
|
||||
|
||||
// 2. Verify server1 is in cooldown and next request goes directly to server2
|
||||
rec2 := httptest.NewRecorder()
|
||||
err2 := svc.Chat(rec2, nil, req)
|
||||
if err2 != nil {
|
||||
t.Fatalf("expected request during cooldown to succeed on server2: %v", err2)
|
||||
}
|
||||
if server2Hits != 2 {
|
||||
t.Fatalf("expected server2 to receive the second request directly, got %d hits", server2Hits)
|
||||
}
|
||||
|
||||
// 3. Test streaming failover when server1 is out of cooldown
|
||||
svc.endpoints[0].CooldownUntil = time.Time{}
|
||||
streamReq := ChatCompletionRequest{
|
||||
Model: "qwen",
|
||||
Messages: []ChatMessage{{Role: "user", Content: "hello"}},
|
||||
Stream: true,
|
||||
}
|
||||
recStream := httptest.NewRecorder()
|
||||
errStream := svc.Chat(recStream, nil, streamReq)
|
||||
if errStream != nil {
|
||||
t.Fatalf("expected streaming failover to succeed, got error: %v", errStream)
|
||||
}
|
||||
if server2Hits != 3 {
|
||||
t.Fatalf("expected server2 to receive the streaming failover, got %d hits", server2Hits)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user