forked from TrueCloudLab/distribution
b9b9cafa8f
Update docs. Change health_test.go tests to create their own registries and register the checks there. The tests now call CheckStatus directly instead of polling the HTTP handler, which returns results from the default registry. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
138 lines
3 KiB
Go
138 lines
3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/docker/distribution/configuration"
|
|
"github.com/docker/distribution/context"
|
|
"github.com/docker/distribution/health"
|
|
)
|
|
|
|
func TestFileHealthCheck(t *testing.T) {
|
|
interval := time.Second
|
|
|
|
tmpfile, err := ioutil.TempFile(os.TempDir(), "healthcheck")
|
|
if err != nil {
|
|
t.Fatalf("could not create temporary file: %v", err)
|
|
}
|
|
defer tmpfile.Close()
|
|
|
|
config := configuration.Configuration{
|
|
Storage: configuration.Storage{
|
|
"inmemory": configuration.Parameters{},
|
|
},
|
|
Health: configuration.Health{
|
|
FileCheckers: []configuration.FileChecker{
|
|
{
|
|
Interval: interval,
|
|
File: tmpfile.Name(),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
app := NewApp(ctx, config)
|
|
healthRegistry := health.NewRegistry()
|
|
app.RegisterHealthChecks(healthRegistry)
|
|
|
|
// Wait for health check to happen
|
|
<-time.After(2 * interval)
|
|
|
|
status := healthRegistry.CheckStatus()
|
|
if len(status) != 1 {
|
|
t.Fatal("expected 1 item in health check results")
|
|
}
|
|
if status[tmpfile.Name()] != "file exists" {
|
|
t.Fatal(`did not get "file exists" result for health check`)
|
|
}
|
|
|
|
os.Remove(tmpfile.Name())
|
|
|
|
<-time.After(2 * interval)
|
|
if len(healthRegistry.CheckStatus()) != 0 {
|
|
t.Fatal("expected 0 items in health check results")
|
|
}
|
|
}
|
|
|
|
func TestHTTPHealthCheck(t *testing.T) {
|
|
interval := time.Second
|
|
threshold := 3
|
|
|
|
stopFailing := make(chan struct{})
|
|
|
|
checkedServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != "HEAD" {
|
|
t.Fatalf("expected HEAD request, got %s", r.Method)
|
|
}
|
|
select {
|
|
case <-stopFailing:
|
|
w.WriteHeader(http.StatusOK)
|
|
default:
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
}))
|
|
|
|
config := configuration.Configuration{
|
|
Storage: configuration.Storage{
|
|
"inmemory": configuration.Parameters{},
|
|
},
|
|
Health: configuration.Health{
|
|
HTTPCheckers: []configuration.HTTPChecker{
|
|
{
|
|
Interval: interval,
|
|
URI: checkedServer.URL,
|
|
Threshold: threshold,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
app := NewApp(ctx, config)
|
|
healthRegistry := health.NewRegistry()
|
|
app.RegisterHealthChecks(healthRegistry)
|
|
|
|
for i := 0; ; i++ {
|
|
<-time.After(interval)
|
|
|
|
status := healthRegistry.CheckStatus()
|
|
|
|
if i < threshold-1 {
|
|
// definitely shouldn't have hit the threshold yet
|
|
if len(status) != 0 {
|
|
t.Fatal("expected 1 item in health check results")
|
|
}
|
|
continue
|
|
}
|
|
if i < threshold+1 {
|
|
// right on the threshold - don't expect a failure yet
|
|
continue
|
|
}
|
|
|
|
if len(status) != 1 {
|
|
t.Fatal("expected 1 item in health check results")
|
|
}
|
|
if status[checkedServer.URL] != "downstream service returned unexpected status: 500" {
|
|
t.Fatal("did not get expected result for health check")
|
|
}
|
|
|
|
break
|
|
}
|
|
|
|
// Signal HTTP handler to start returning 200
|
|
close(stopFailing)
|
|
|
|
<-time.After(2 * interval)
|
|
|
|
if len(healthRegistry.CheckStatus()) != 0 {
|
|
t.Fatal("expected 0 items in health check results")
|
|
}
|
|
}
|