feat(go): add platform principles and health probes
This commit is contained in:
98
go/vehicle-gateway/internal/health/health_test.go
Normal file
98
go/vehicle-gateway/internal/health/health_test.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package health
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHandlerReturnsHealthyWhenAllChecksPass(t *testing.T) {
|
||||
handler := NewHandler("vehicle-realtime-api", []Check{
|
||||
{Name: "redis", Check: func(context.Context) error { return nil }},
|
||||
{Name: "mysql", Check: func(context.Context) error { return nil }},
|
||||
})
|
||||
request := httptest.NewRequest(http.MethodGet, "/readyz", nil)
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(response, request)
|
||||
|
||||
if response.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d body=%s", response.Code, response.Body.String())
|
||||
}
|
||||
body := response.Body.String()
|
||||
for _, want := range []string{`"service":"vehicle-realtime-api"`, `"status":"ok"`, `"redis":{"status":"ok"`, `"mysql":{"status":"ok"`} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("response missing %s: %s", want, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlerReturnsServiceUnavailableWhenCheckFails(t *testing.T) {
|
||||
handler := NewHandler("vehicle-history-writer", []Check{
|
||||
{Name: "tdengine", Check: func(context.Context) error { return errors.New("ping failed") }},
|
||||
})
|
||||
request := httptest.NewRequest(http.MethodGet, "/readyz", nil)
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(response, request)
|
||||
|
||||
if response.Code != http.StatusServiceUnavailable {
|
||||
t.Fatalf("status = %d body=%s", response.Code, response.Body.String())
|
||||
}
|
||||
body := response.Body.String()
|
||||
for _, want := range []string{`"service":"vehicle-history-writer"`, `"status":"degraded"`, `"tdengine":`, `"status":"error"`, `"error":"ping failed"`} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("response missing %s: %s", want, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlerRejectsUnknownPath(t *testing.T) {
|
||||
handler := NewHandler("vehicle-gateway", nil)
|
||||
request := httptest.NewRequest(http.MethodGet, "/metrics", nil)
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(response, request)
|
||||
|
||||
if response.Code != http.StatusNotFound {
|
||||
t.Fatalf("status = %d body=%s", response.Code, response.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewMuxRegistersHealthAndReadinessRoutes(t *testing.T) {
|
||||
mux := NewMux("vehicle-stat-writer", []Check{
|
||||
{Name: "mysql", Check: func(context.Context) error { return nil }},
|
||||
})
|
||||
for _, path := range []string{"/healthz", "/readyz"} {
|
||||
request := httptest.NewRequest(http.MethodGet, path, nil)
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
mux.ServeHTTP(response, request)
|
||||
|
||||
if response.Code != http.StatusOK {
|
||||
t.Fatalf("%s status = %d body=%s", path, response.Code, response.Body.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewServerReturnsNilWhenAddressIsEmpty(t *testing.T) {
|
||||
if server := NewServer("", "vehicle-gateway", nil); server != nil {
|
||||
t.Fatalf("server = %#v, want nil", server)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewServerBuildsConfiguredHTTPServer(t *testing.T) {
|
||||
server := NewServer(":20290", "vehicle-gateway", nil)
|
||||
if server == nil {
|
||||
t.Fatal("server is nil")
|
||||
}
|
||||
if server.Addr != ":20290" {
|
||||
t.Fatalf("addr = %q", server.Addr)
|
||||
}
|
||||
if server.ReadHeaderTimeout == 0 {
|
||||
t.Fatal("ReadHeaderTimeout should be configured")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user