mirror of
https://github.com/stefanprodan/podinfo.git
synced 2026-08-20 12:46:42 +00:00
131 lines
4.2 KiB
Go
131 lines
4.2 KiB
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"sync/atomic"
|
|
"testing"
|
|
)
|
|
|
|
func TestFaultInjection_EnableDisable(t *testing.T) {
|
|
defer atomic.StoreInt32(&faultInjection, 0)
|
|
srv := NewMockServer()
|
|
|
|
rr := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/fault_injection/enable", nil)
|
|
http.HandlerFunc(srv.enableFaultInjectionHandler).ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusAccepted {
|
|
t.Fatalf("enable: got %d want %d", rr.Code, http.StatusAccepted)
|
|
}
|
|
if ct := rr.Header().Get("Content-Type"); !strings.HasPrefix(ct, "application/json") {
|
|
t.Errorf("enable: Content-Type = %q, want application/json", ct)
|
|
}
|
|
if !strings.Contains(rr.Body.String(), `"enabled"`) {
|
|
t.Errorf("enable: expected enabled in body, got: %s", rr.Body.String())
|
|
}
|
|
if atomic.LoadInt32(&faultInjection) != 1 {
|
|
t.Fatalf("faultInjection flag not set after enable")
|
|
}
|
|
|
|
rr = httptest.NewRecorder()
|
|
req, _ = http.NewRequest("POST", "/fault_injection/disable", nil)
|
|
http.HandlerFunc(srv.disableFaultInjectionHandler).ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusAccepted {
|
|
t.Fatalf("disable: got %d want %d", rr.Code, http.StatusAccepted)
|
|
}
|
|
if ct := rr.Header().Get("Content-Type"); !strings.HasPrefix(ct, "application/json") {
|
|
t.Errorf("disable: Content-Type = %q, want application/json", ct)
|
|
}
|
|
if !strings.Contains(rr.Body.String(), `"disabled"`) {
|
|
t.Errorf("disable: expected disabled in body, got: %s", rr.Body.String())
|
|
}
|
|
if atomic.LoadInt32(&faultInjection) != 0 {
|
|
t.Fatalf("faultInjection flag not cleared after disable")
|
|
}
|
|
}
|
|
|
|
func TestFaultInjection_StatusHandler(t *testing.T) {
|
|
defer atomic.StoreInt32(&faultInjection, 0)
|
|
srv := NewMockServer()
|
|
|
|
rr := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/fault_injection/status", nil)
|
|
http.HandlerFunc(srv.faultInjectionStatusHandler).ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusOK {
|
|
t.Fatalf("status: got %d want %d", rr.Code, http.StatusOK)
|
|
}
|
|
if !strings.Contains(rr.Body.String(), "disabled") {
|
|
t.Errorf("expected disabled in body, got: %s", rr.Body.String())
|
|
}
|
|
|
|
atomic.StoreInt32(&faultInjection, 1)
|
|
rr = httptest.NewRecorder()
|
|
http.HandlerFunc(srv.faultInjectionStatusHandler).ServeHTTP(rr, req)
|
|
if !strings.Contains(rr.Body.String(), "enabled") {
|
|
t.Errorf("expected enabled in body, got: %s", rr.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestFaultInjectionMiddleware(t *testing.T) {
|
|
ok := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte("ok"))
|
|
})
|
|
h := faultInjectionMiddleware(ok)
|
|
|
|
cases := []struct {
|
|
name string
|
|
path string
|
|
injected bool
|
|
wantStatus int
|
|
}{
|
|
{"disabled passes through", "/", false, http.StatusOK},
|
|
{"enabled returns 500 for app path", "/", true, http.StatusInternalServerError},
|
|
{"enabled returns 500 for arbitrary path", "/api/info", true, http.StatusInternalServerError},
|
|
{"enabled excludes healthz", "/healthz", true, http.StatusOK},
|
|
{"enabled excludes readyz", "/readyz", true, http.StatusOK},
|
|
{"enabled excludes metrics", "/metrics", true, http.StatusOK},
|
|
{"enabled excludes debug pprof", "/debug/pprof/", true, http.StatusOK},
|
|
{"enabled excludes fault_injection control", "/fault_injection/disable", true, http.StatusOK},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if tc.injected {
|
|
atomic.StoreInt32(&faultInjection, 1)
|
|
} else {
|
|
atomic.StoreInt32(&faultInjection, 0)
|
|
}
|
|
defer atomic.StoreInt32(&faultInjection, 0)
|
|
|
|
req, _ := http.NewRequest("GET", tc.path, nil)
|
|
rr := httptest.NewRecorder()
|
|
h.ServeHTTP(rr, req)
|
|
if rr.Code != tc.wantStatus {
|
|
t.Fatalf("path %s: got %d want %d", tc.path, rr.Code, tc.wantStatus)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFaultInjectionExcluded(t *testing.T) {
|
|
cases := map[string]bool{
|
|
"/": false,
|
|
"/api/info": false,
|
|
"/healthz": true,
|
|
"/readyz": true,
|
|
"/metrics": true,
|
|
"/debug/pprof/": true,
|
|
"/fault_injection/enable": true,
|
|
"/fault_injection/disable": true,
|
|
"/fault_injection/status": true,
|
|
"/healthzz": false,
|
|
}
|
|
for p, want := range cases {
|
|
if got := faultInjectionExcluded(p); got != want {
|
|
t.Errorf("faultInjectionExcluded(%q) = %v, want %v", p, got, want)
|
|
}
|
|
}
|
|
}
|