Adds health check and test
This commit is contained in:
parent
0e16bb5361
commit
e77d3c4d5e
58
routes/health.go
Normal file
58
routes/health.go
Normal file
@ -0,0 +1,58 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"gitea.deepak.science/deepak/gogmagog/models"
|
||||
"github.com/go-chi/chi"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func newHealthRouter(m *models.Model) http.Handler {
|
||||
router := chi.NewRouter()
|
||||
router.Get("/", getHealthFunc(m))
|
||||
return router
|
||||
}
|
||||
|
||||
type healthCheck struct {
|
||||
Name string `json:"name"`
|
||||
Healthy bool `json:"healthy"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func getHealthFunc(m *models.Model) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var healths []*healthCheck
|
||||
|
||||
healths = append(healths, dbHealth(m))
|
||||
|
||||
code := http.StatusOK
|
||||
for _, h := range healths {
|
||||
if !h.Healthy {
|
||||
code = http.StatusInternalServerError
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteHeader(code)
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(healths); err != nil {
|
||||
serverError(w, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func dbHealth(m *models.Model) *healthCheck {
|
||||
errMessage := ""
|
||||
health := true
|
||||
name := "Store"
|
||||
err := m.Healthy()
|
||||
if err != nil {
|
||||
errMessage = err.Error()
|
||||
health = false
|
||||
}
|
||||
return &healthCheck{
|
||||
Name: name,
|
||||
Healthy: health,
|
||||
Message: errMessage,
|
||||
}
|
||||
}
|
87
routes/health_test.go
Normal file
87
routes/health_test.go
Normal file
@ -0,0 +1,87 @@
|
||||
package routes_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.deepak.science/deepak/gogmagog/routes"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEmptyHeatlhErrorWriter(t *testing.T) {
|
||||
// set up
|
||||
assert := assert.New(t)
|
||||
|
||||
m := getEmptyModel()
|
||||
|
||||
router := routes.NewRouter(m)
|
||||
req, _ := http.NewRequest("GET", "/health", nil)
|
||||
|
||||
rr := NewBadWriter()
|
||||
|
||||
// function under test
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
// check results
|
||||
status := rr.Code
|
||||
assert.Equal(http.StatusInternalServerError, status)
|
||||
|
||||
}
|
||||
|
||||
func TestEmptyHealth(t *testing.T) {
|
||||
// set up
|
||||
assert := assert.New(t)
|
||||
m := getEmptyModel()
|
||||
router := routes.NewRouter(m)
|
||||
req, _ := http.NewRequest("GET", "/health", nil)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
// function under test
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
// check results
|
||||
status := rr.Code
|
||||
assert.Equal(http.StatusOK, status)
|
||||
expected := `[
|
||||
{
|
||||
"name": "Store",
|
||||
"healthy": true,
|
||||
"message": ""
|
||||
}
|
||||
]`
|
||||
|
||||
assert.JSONEq(expected, rr.Body.String())
|
||||
contentType := rr.Header().Get("Content-Type")
|
||||
assert.Equal("application/json", contentType)
|
||||
}
|
||||
|
||||
func TestUnhealthyDB(t *testing.T) {
|
||||
// set up
|
||||
assert := assert.New(t)
|
||||
errorMsg := "error"
|
||||
m := getErrorModel(errorMsg)
|
||||
router := routes.NewRouter(m)
|
||||
req, _ := http.NewRequest("GET", "/health", nil)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
// function under test
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
// check results
|
||||
status := rr.Code
|
||||
assert.Equal(http.StatusInternalServerError, status)
|
||||
expected := fmt.Sprintf(`[
|
||||
{
|
||||
"name": "Store",
|
||||
"healthy": false,
|
||||
"message": "%s"
|
||||
}
|
||||
]`, errorMsg)
|
||||
|
||||
assert.JSONEq(expected, rr.Body.String())
|
||||
contentType := rr.Header().Get("Content-Type")
|
||||
assert.Equal("application/json", contentType)
|
||||
}
|
@ -66,7 +66,7 @@ func TestErrorPlan(t *testing.T) {
|
||||
// set up
|
||||
assert := assert.New(t)
|
||||
|
||||
m := getErrorModel()
|
||||
m := getErrorModel("Model always errors")
|
||||
|
||||
router := routes.NewRouter(m)
|
||||
req, _ := http.NewRequest("GET", "/plans", nil)
|
||||
|
@ -87,7 +87,7 @@ type errorStore struct {
|
||||
error error
|
||||
}
|
||||
|
||||
func getErrorModel() *models.Model {
|
||||
e := &errorStore{error: fmt.Errorf("Model always errors")}
|
||||
func getErrorModel(errorMsg string) *models.Model {
|
||||
e := &errorStore{error: fmt.Errorf(errorMsg)}
|
||||
return models.New(e)
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ func NewRouter(m *models.Model) http.Handler {
|
||||
router.MethodNotAllowed(methodNotAllowedHandler)
|
||||
router.NotFound(notFoundHandler)
|
||||
router.Mount("/plans", newPlanRouter(m))
|
||||
router.Mount("/health", newHealthRouter(m))
|
||||
router.Get("/ping", ping)
|
||||
return router
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user