Skip to content

Commit

Permalink
Added tests for health checks (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitaly Karpenko authored and Evgeniy-L committed Apr 12, 2018
1 parent f2e4fd9 commit 1c541f7
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 38 deletions.
28 changes: 0 additions & 28 deletions health/checkers.go

This file was deleted.

13 changes: 13 additions & 0 deletions health/dnsprobecheck_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package health

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestDNSProbeCheck(t *testing.T) {
assert.NoError(t, DNSProbeCheck("google.com", 5*time.Second)())
assert.Error(t, DNSProbeCheck("never.ever.where.com", 5*time.Second)())
}
24 changes: 14 additions & 10 deletions health/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ func (ch *checksHandler) healthEndpoint(rw http.ResponseWriter, r *http.Request)
}

func (ch *checksHandler) readyEndpoint(rw http.ResponseWriter, r *http.Request) {
ch.handle(rw, r, ch.readinessChecks)
ch.handle(rw, r, ch.readinessChecks, ch.livenessChecks)
}

func (ch *checksHandler) handle(rw http.ResponseWriter, r *http.Request, checks map[string]Check) {
func (ch *checksHandler) handle(rw http.ResponseWriter, r *http.Request, checksSets ...map[string]Check) {
if r.Method != http.MethodGet {
http.Error(rw, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
Expand All @@ -74,18 +74,22 @@ func (ch *checksHandler) handle(rw http.ResponseWriter, r *http.Request, checks
status := http.StatusOK
ch.lock.RLock()
defer ch.lock.RUnlock()
for name, check := range checks {
if check == nil {
continue
}
if err := check(); err != nil {
status = http.StatusServiceUnavailable
errors[name] = err

for _, checks := range checksSets {
for name, check := range checks {
if check == nil {
continue
}
if err := check(); err != nil {
status = http.StatusServiceUnavailable
errors[name] = err
}
}
}

rw.WriteHeader(status)

return

// Uncomment to write errors and get non-empty response
// rw.Header().Set("Content-Type", "application/json; charset=utf-8")
// if status == http.StatusOK {
Expand Down
107 changes: 107 additions & 0 deletions health/handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package health

import (
"errors"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
)

func TestNewHandler(t *testing.T) {
var tests = []struct {
name string
method string
path string
failHealth bool
failReady bool
expectedCode int
}{
{
name: "Non-existent URL",
method: http.MethodPost,
path: "/neverwhere",
expectedCode: http.StatusNotFound,
},
{
name: "POST Method not allowed health",
method: http.MethodPost,
path: "/healthz",
expectedCode: http.StatusMethodNotAllowed,
},
{
name: "POST Method not allowed ready",
method: http.MethodPost,
path: "/ready",
expectedCode: http.StatusMethodNotAllowed,
},
{
name: "No checks health",
method: http.MethodGet,
path: "/healthz",
expectedCode: http.StatusOK,
},
{
name: "No checks ready",
method: http.MethodGet,
path: "/ready",
expectedCode: http.StatusOK,
},
{
name: "Health succeed Ready fail health",
method: http.MethodGet,
path: "/healthz",
expectedCode: http.StatusOK,
failReady: true,
},
{
name: "Health succeed Ready fail ready",
method: http.MethodGet,
path: "/ready",
expectedCode: http.StatusServiceUnavailable,
failReady: true,
},
{
name: "Health fail Ready succeed health",
method: http.MethodGet,
path: "/healthz",
expectedCode: http.StatusServiceUnavailable,
failHealth: true,
},
{
name: "Health fail Ready succeed ready",
method: http.MethodGet,
path: "/ready",
expectedCode: http.StatusServiceUnavailable,
failHealth: true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
h := NewChecksHandler("/healthz", "/ready")

if test.failHealth {
h.AddLiveness("Liveness check test", func() error {
return errors.New("Liveness check failed")
})
}

if test.failReady {
h.AddReadiness("Readiness check test", func() error {
return errors.New("Readiness check failed")
})
}

req, err := http.NewRequest(test.method, test.path, nil)
assert.NoError(t, err)

reqStr := test.method + " " + test.path
httpRecorder := httptest.NewRecorder()
h.Handler().ServeHTTP(httpRecorder, req)
assert.Equal(t, test.expectedCode, httpRecorder.Code,
"Result codes don't match %q. [%s]", reqStr, test.name)
})
}
}
14 changes: 14 additions & 0 deletions health/httpgetcheck_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package health

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestHTTPGetCheck(t *testing.T) {
assert.NoError(t, HTTPGetCheck("http://httpbin.org/get", 5*time.Second)(), "Simple HTTP GET request shouldn't fail")
assert.Error(t, HTTPGetCheck("http://httpbin.org/relative-redirect/:1", 5*time.Second)(), "Redirrect is not HTTP 200: OK")
assert.Error(t, HTTPGetCheck("http://httpbin.org/nonexistent", 5*time.Second)(), "Non-existing site exists")
}

0 comments on commit 1c541f7

Please sign in to comment.