Beispiel #1
0
func TestUnmarhsalJSON(t *testing.T) {
	testcases := []struct {
		encoded []byte        // encoded JSON
		status  health.Status // expected object
	}{
		{[]byte(`{"healthy":true}`), health.Healthy},
		{[]byte(`{"healthy":true,"properties":{"message":"service is up"}}`), health.StatusHealthy("service is up")},
		{[]byte(`{}`), health.StatusUnhealthy("", nil)},
		{[]byte(`{"healthy":false,"properties":{"message":"service is down"}}`), health.StatusUnhealthy("service is down", nil)},
		{[]byte(`{"healthy":false,"properties":{"cause":"network unreachable"}}`), health.StatusUnhealthy("", errors.New("network unreachable"))},
		{[]byte(`{"healthy":false,"properties":{"message":"service is down","cause":"network unreachable"}}`),
			health.StatusUnhealthy("service is down", errors.New("network unreachable"))},
		{[]byte(`{"healthy":true,"properties":{"message":"ok","size":3.0, "sync":true}}`),
			health.StatusHealthyWithProperties(map[string]interface{}{"message": "ok", "size": 3.0, "sync": true})},
		{[]byte(`{"healthy":false,"properties":{"message":"ok","size":3.0, "sync":true}}`),
			health.StatusUnhealthyWithProperties(map[string]interface{}{"message": "ok", "size": 3.0, "sync": true})},
	}

	for _, s := range testcases {
		decoded := &health.Status{}
		err := json.Unmarshal(s.encoded, decoded)
		assert.Nil(t, err)
		if err != nil {
			println(err.Error())
		}
		assert.EqualValues(t, s.status, *decoded)
	}
}
Beispiel #2
0
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()
}
Beispiel #3
0
func TestMarhsalJSONUnhealthy(t *testing.T) {
	testcases := []health.Status{
		health.StatusUnhealthy("", nil),
		health.StatusUnhealthy("service is down", nil),
		health.StatusUnhealthy("", errors.New("network unreachable")),
		health.StatusUnhealthy("service is down", errors.New("network unreachable")),
		health.StatusUnhealthyWithProperties(map[string]interface{}{"message": "ok", "size": 3.0, "sync": true}),
	}

	for _, s := range testcases {
		b, err := json.Marshal(s)
		assert.Nil(t, err)
		decoded := &health.Status{}
		err = json.Unmarshal(b, decoded)
		assert.Nil(t, err)
		if err != nil {
			println(err.Error())
		}
		assert.EqualValues(t, s, *decoded)
	}
}
Beispiel #4
0
func (hc *healthChecker) Check() health.Status {
	hc.mutex.Lock()
	defer hc.mutex.Unlock()

	now := time.Now()
	numDisconnected := 0
	minDuration := time.Duration(0)

	for id, health := range hc.clients {

		wasConnected := health.connected
		health.connected = health.cl.isConnected()

		if !health.connected {
			if wasConnected {
				health.disconnectedTime = now
			}
			disconnectedDuration := now.Sub(health.disconnectedTime)
			if disconnectedDuration > hc.disconnectedThreshold {
				hc.logger.Warningf("Peer %v replication client disconnected for %v", id, disconnectedDuration)
				numDisconnected++
				if numDisconnected == 1 || (minDuration > disconnectedDuration) {
					minDuration = disconnectedDuration
				}
			}
		}
	}

	if numDisconnected > 0 {
		message := fmt.Sprintf(
			"%d/%d replication clients disconnected for at least %v",
			numDisconnected, len(hc.clients), minDuration)
		return health.StatusUnhealthy(message, nil)
	}
	return health.Healthy

}
Beispiel #5
0
func TestStatusCause(t *testing.T) {
	e := errors.New("invalid")
	uh := health.StatusUnhealthy("failed", e)
	assert.Equal(t, e.Error(), uh.Properties["cause"])
}
Beispiel #6
0
func TestStatusUnhealthy(t *testing.T) {
	uh := health.StatusUnhealthy("failed", nil)
	assert.False(t, uh.Healthy)
}
Beispiel #7
0
func alwaysFailing() health.Status {
	return health.StatusUnhealthy(FAILING, errors.New("undefined failure"))
}
Beispiel #8
0
func (stub *stubHealthCheck) Check() health.Status {
	if stub.healthy {
		return health.StatusHealthy("I'm a lumberjack and I'm OK")
	}
	return health.StatusUnhealthy(FAILING, nil)
}
Beispiel #9
0
	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()
}

//-----------------------------------------------------------------------------
// publishing health checks
var published = map[string]health.CheckerFunc{
	"pass":  func() health.Status { return health.Healthy },
	"fail":  func() health.Status { return health.StatusUnhealthy(FAILING, nil) },
	"panic": func() health.Status { panic("oops!") },
}

func TestHTTPHandlerSuccess(t *testing.T) {
	testCase := "pass"
	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.HTTPStatusCodeHealthChecksPass, w.Code)
	teardown()
}