mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-07-26 07:48:13 +00:00
46aa3752c8
Signed-off-by: Noste <83548733+Noooste@users.noreply.github.com>
150 lines
4.4 KiB
Go
150 lines
4.4 KiB
Go
package services
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"Noooste/garage-ui/internal/config"
|
|
)
|
|
|
|
func TestErrUnsupportedIsSentinel(t *testing.T) {
|
|
err := ErrUnsupported
|
|
if !errors.Is(err, ErrUnsupported) {
|
|
t.Fatal("ErrUnsupported should match itself via errors.Is")
|
|
}
|
|
}
|
|
|
|
func TestCapabilitiesV2AllTrue(t *testing.T) {
|
|
caps := CapabilitiesV2()
|
|
if !caps.ClusterStatistics || !caps.NodeInfo || !caps.NodeStatistics {
|
|
t.Fatalf("v2 capabilities should all be true, got %+v", caps)
|
|
}
|
|
}
|
|
|
|
func TestCapabilitiesV1AllFalse(t *testing.T) {
|
|
caps := CapabilitiesV1()
|
|
if caps.ClusterStatistics || caps.NodeInfo || caps.NodeStatistics {
|
|
t.Fatalf("v1 capabilities should all be false, got %+v", caps)
|
|
}
|
|
}
|
|
|
|
func TestDetectVersion_V2(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/v2/GetClusterHealth" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"status":"healthy"}`))
|
|
return
|
|
}
|
|
w.WriteHeader(404)
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cfg := &config.GarageConfig{AdminEndpoint: srv.URL, AdminToken: "tok"}
|
|
result, err := NewAdminService(cfg, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result.APIVersion != "v2" {
|
|
t.Fatalf("expected v2, got %s", result.APIVersion)
|
|
}
|
|
if !result.Capabilities.ClusterStatistics {
|
|
t.Fatal("v2 should have ClusterStatistics capability")
|
|
}
|
|
}
|
|
|
|
func TestDetectVersion_V1(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/v2/GetClusterHealth" {
|
|
w.WriteHeader(404)
|
|
return
|
|
}
|
|
if r.URL.Path == "/v1/health" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"status":"healthy"}`))
|
|
return
|
|
}
|
|
w.WriteHeader(404)
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cfg := &config.GarageConfig{AdminEndpoint: srv.URL, AdminToken: "tok"}
|
|
result, err := NewAdminService(cfg, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result.APIVersion != "v1" {
|
|
t.Fatalf("expected v1, got %s", result.APIVersion)
|
|
}
|
|
if result.Capabilities.ClusterStatistics {
|
|
t.Fatal("v1 should not have ClusterStatistics capability")
|
|
}
|
|
}
|
|
|
|
func TestDetectVersion_Unreachable(t *testing.T) {
|
|
cfg := &config.GarageConfig{AdminEndpoint: "http://127.0.0.1:1", AdminToken: "tok"}
|
|
_, err := NewAdminService(cfg, "")
|
|
if err == nil {
|
|
t.Fatal("expected error for unreachable server")
|
|
}
|
|
}
|
|
|
|
// Garage v2.x serves /v1/health too, so a transient failure of the /v2 probe
|
|
// must not cause a permanent downgrade to the (broken on v2.x) v1 client.
|
|
// Regression test for https://github.com/Noooste/garage-ui/issues/78
|
|
func TestDetectVersion_V2_TransientProbeFailure(t *testing.T) {
|
|
var v2Hits int
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.URL.Path {
|
|
case "/v2/GetClusterHealth":
|
|
v2Hits++
|
|
if v2Hits < 3 { // fail the first two attempts, then recover
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"status":"healthy"}`))
|
|
case "/v1/health": // v2.x still answers this
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"status":"healthy"}`))
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cfg := &config.GarageConfig{AdminEndpoint: srv.URL, AdminToken: "tok"}
|
|
result, err := NewAdminService(cfg, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result.APIVersion != "v2" {
|
|
t.Fatalf("expected v2 after transient probe failure, got %s", result.APIVersion)
|
|
}
|
|
}
|
|
|
|
// A server that answers /v1/health but returns a server error (not 404) for
|
|
// /v2/GetClusterHealth must NOT be detected as v1, because v2.x servers also
|
|
// answer /v1/health. Falling through to v1 here is the issue #78 misdetection.
|
|
func TestDetectVersion_DoesNotDowngradeOnV2ServerError(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.URL.Path {
|
|
case "/v2/GetClusterHealth":
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
case "/v1/health":
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"status":"healthy"}`))
|
|
default:
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
cfg := &config.GarageConfig{AdminEndpoint: srv.URL, AdminToken: "tok"}
|
|
result, err := NewAdminService(cfg, "")
|
|
if err == nil && result.APIVersion == "v1" {
|
|
t.Fatal("must not downgrade to v1 when /v2 returns a server error; v2.x also serves /v1/health")
|
|
}
|
|
}
|