mirror of
https://gitcode.com/JianFeeeee/webui4frpc.git
synced 2026-09-20 00:47:57 +00:00
feat: M3 load balancing + health check (model/render/admin API status/UI)
This commit is contained in:
@ -6,6 +6,8 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"webui4frpc/internal/process"
|
||||
@ -138,3 +140,55 @@ func TestSettingsPutRoundTrip(t *testing.T) {
|
||||
t.Fatalf("settings after reload = %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestFetchProxyStatesFromAdminAPI verifies the M3 status path: we mock the
|
||||
// frpc admin API (/api/status with Basic Auth) and confirm fetchProxyStates
|
||||
// parses per-proxy rows and connStateAdmin derives the right summary.
|
||||
func TestFetchProxyStatesFromAdminAPI(t *testing.T) {
|
||||
// Mock frpc admin server.
|
||||
admin := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
u, p, ok := r.BasicAuth()
|
||||
if !ok || u != "admin" || p != "pw" {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
if r.URL.Path != "/api/status" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string][]proxyState{
|
||||
"tcp": {
|
||||
{Name: "web1", Type: "tcp", Status: "running", LocalAddr: "127.0.0.1:8080", RemoteAddr: "1.2.3.4:8080"},
|
||||
{Name: "web2", Type: "tcp", Status: "check failed", Err: "health check failed"},
|
||||
},
|
||||
})
|
||||
}))
|
||||
defer admin.Close()
|
||||
u := strings.TrimPrefix(admin.URL, "http://")
|
||||
host, portStr, _ := strings.Cut(u, ":")
|
||||
port, _ := strconv.Atoi(portStr)
|
||||
|
||||
states, err := fetchProxyStates(host, port, "admin", "pw")
|
||||
if err != nil {
|
||||
t.Fatalf("fetchProxyStates: %v", err)
|
||||
}
|
||||
if len(states) != 2 {
|
||||
t.Fatalf("states = %+v", states)
|
||||
}
|
||||
if states[0].Status != "running" || states[1].Status != "check failed" {
|
||||
t.Fatalf("unexpected states = %+v", states)
|
||||
}
|
||||
|
||||
// connStateAdmin: one running -> connected.
|
||||
if got := connStateAdmin(states); got != "connected" {
|
||||
t.Fatalf("connStateAdmin = %q, want connected", got)
|
||||
}
|
||||
// All failed -> failed.
|
||||
if got := connStateAdmin([]proxyState{{Name: "a", Status: "check failed"}, {Name: "b", Status: "start error"}}); got != "failed" {
|
||||
t.Fatalf("connStateAdmin(all failed) = %q, want failed", got)
|
||||
}
|
||||
// wait start -> connecting.
|
||||
if got := connStateAdmin([]proxyState{{Name: "a", Status: "wait start"}}); got != "connecting" {
|
||||
t.Fatalf("connStateAdmin(wait start) = %q, want connecting", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user