func TestHTTPHandlerPartialFail(t *testing.T) { testCase := "pass" health.RegisterFunc(testCase, published[testCase]) testCase = "fail" health.RegisterFunc(testCase, published[testCase]) handler := health.Handler() req, err := http.NewRequest("GET", "http://ignored.path.to.dontcare.example.com/", nil) assert.Nil(t, err) w := httptest.NewRecorder() handler(w, req) assert.Equal(t, health.HTTPStatusCodeHealthChecksFail, w.Code) teardown() }
func TestHTTPHandlerReturnsAll(t *testing.T) { for name, fn := range published { health.RegisterFunc(name, fn) } handler := health.Handler() req, err := http.NewRequest("GET", "http://ignored.path.to.dontcare.example.com/", nil) assert.Nil(t, err) w := httptest.NewRecorder() handler(w, req) assert.Equal(t, health.HTTPStatusCodeHealthChecksFail, w.Code) var actual map[string]health.Status assert.Nil(t, json.Unmarshal(w.Body.Bytes(), &actual)) var expected = map[string]health.Status{ "pass": health.Healthy, "fail": health.StatusUnhealthy(FAILING, nil), "panic": health.StatusUnhealthy(health.CheckPanicked, errors.New("oops!")), } assert.Len(t, actual, len(expected)) assert.EqualValues(t, actual, expected) teardown() }
func TestRegisterFunc(t *testing.T) { health.RegisterFunc(COMPONENT, alwaysFailing) assert.Len(t, health.Components(), 1) assert.Contains(t, health.Components(), COMPONENT) all := health.RunChecks() status, found := all[COMPONENT] assert.True(t, found) assert.EqualValues(t, status, alwaysFailing()) teardown() }
func TestRegisterDuplicateHealthCheck(t *testing.T) { health.Register(COMPONENT, healthy) health.RegisterFunc(COMPONENT, alwaysFailing) // replace with failing health check assert.Len(t, health.Components(), 1) assert.Contains(t, health.Components(), COMPONENT) all := health.RunChecks() status, found := all[COMPONENT] assert.True(t, found) assert.EqualValues(t, status, alwaysFailing()) teardown() }
//----------------------------------------------------------------------------- // recover from health check panic and mark component as failing func TestRecoverFromHealthCheckPanic(t *testing.T) { cause := "oops I did it again" health.RegisterFunc("Will panic", func() health.Status { panic(cause) }) checks := health.RunChecks() assert.Len(t, checks, 1) for _, hc := range checks { assert.False(t, hc.Healthy) assert.Equal(t, health.CheckPanicked, hc.Properties["message"]) assert.Equal(t, cause, hc.Properties["cause"]) } teardown() }
func TestParallelExecution(t *testing.T) { start := time.Now() expected_end := start.Add(time.Second) for i := 0; i < 5; i++ { health.RegisterFunc(fmt.Sprint("Sleeper-", i), func() health.Status { time.Sleep(1 * time.Second) return health.Healthy }) } _ = health.RunChecks() // we don't really expect it to diverge by more than ~100ms, to avoid false negatives, allow one // second drift - still considerably less than the 5s if running checks sequenctially assert.WithinDuration(t, expected_end, time.Now(), time.Second, "not running concurrently") teardown() }