core/internal/health/healthhttp/handler_test.go

193 lines
4.8 KiB
Go

package healthhttp_test
import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"time"
"gitea.dwysokinski.me/twhelp/corev3/internal/health"
"gitea.dwysokinski.me/twhelp/corev3/internal/health/healthhttp"
"gitea.dwysokinski.me/twhelp/corev3/internal/health/healthtest"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestReadyHandler(t *testing.T) {
t.Parallel()
tests := []struct {
name string
options []health.Option
expectedStatus int
expectedResponse healthhttp.Response
}{
{
name: "pass",
options: []health.Option{
health.WithReadyCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithReadyCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithReadyCheck(healthtest.Checker{Nam: "test2", Err: nil}),
},
expectedStatus: http.StatusOK,
expectedResponse: healthhttp.Response{
Status: health.StatusPass.String(),
Checks: map[string][]healthhttp.SingleCheckResult{
"test": {
{
Status: health.StatusPass.String(),
},
{
Status: health.StatusPass.String(),
},
},
"test2": {
{
Status: health.StatusPass.String(),
},
},
},
},
},
{
name: "2 checks passed, 1 check failed",
options: []health.Option{
health.WithReadyCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithReadyCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithReadyCheck(healthtest.Checker{Nam: "test2", Err: errors.New("failed")}),
},
expectedStatus: http.StatusServiceUnavailable,
expectedResponse: healthhttp.Response{
Status: health.StatusFail.String(),
Checks: map[string][]healthhttp.SingleCheckResult{
"test": {
{
Status: health.StatusPass.String(),
},
{
Status: health.StatusPass.String(),
},
},
"test2": {
{
Status: health.StatusFail.String(),
FailureReason: "failed",
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
rr := httptest.NewRecorder()
healthhttp.ReadyHandler(health.New(tt.options...)).ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/readyz", nil))
assert.Equal(t, tt.expectedStatus, rr.Code)
assert.Equal(t, "application/json", rr.Header().Get("Content-Type"))
var body healthhttp.Response
require.NoError(t, json.NewDecoder(rr.Body).Decode(&body))
assert.Empty(t, cmp.Diff(
tt.expectedResponse,
body,
cmpopts.IgnoreTypes(time.Time{}),
))
})
}
}
func TestLiveHandler(t *testing.T) {
t.Parallel()
tests := []struct {
name string
options []health.Option
expectedStatus int
expectedResponse healthhttp.Response
}{
{
name: "pass",
options: []health.Option{
health.WithLiveCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithLiveCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithLiveCheck(healthtest.Checker{Nam: "test2", Err: nil}),
},
expectedStatus: http.StatusOK,
expectedResponse: healthhttp.Response{
Status: health.StatusPass.String(),
Checks: map[string][]healthhttp.SingleCheckResult{
"test": {
{
Status: health.StatusPass.String(),
},
{
Status: health.StatusPass.String(),
},
},
"test2": {
{
Status: health.StatusPass.String(),
},
},
},
},
},
{
name: "2 checks passed, 1 check failed",
options: []health.Option{
health.WithLiveCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithLiveCheck(healthtest.Checker{Nam: "test", Err: nil}),
health.WithLiveCheck(healthtest.Checker{Nam: "test2", Err: errors.New("failed")}),
},
expectedStatus: http.StatusServiceUnavailable,
expectedResponse: healthhttp.Response{
Status: health.StatusFail.String(),
Checks: map[string][]healthhttp.SingleCheckResult{
"test": {
{
Status: health.StatusPass.String(),
},
{
Status: health.StatusPass.String(),
},
},
"test2": {
{
Status: health.StatusFail.String(),
FailureReason: "failed",
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
rr := httptest.NewRecorder()
healthhttp.LiveHandler(health.New(tt.options...)).ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/livez", nil))
assert.Equal(t, tt.expectedStatus, rr.Code)
assert.Equal(t, "application/json", rr.Header().Get("Content-Type"))
var body healthhttp.Response
require.NoError(t, json.NewDecoder(rr.Body).Decode(&body))
assert.Empty(t, cmp.Diff(
tt.expectedResponse,
body,
cmpopts.IgnoreTypes(time.Time{}),
))
})
}
}