Example #1
0
func DefaultHealthyHandler(w http.ResponseWriter, r *http.Request) {
	err := httputil.WriteJSONResponse(w, http.StatusOK, StatusResponse{
		Status: "ok",
	})
	if err != nil {
		// TODO(bobbyrullo): replace with logging from new logging pkg,
		// once it lands.
		log.Printf("Failed to write JSON response: %v", err)
	}
}
Example #2
0
func DefaultUnhealthyHandler(w http.ResponseWriter, r *http.Request, err error) {
	writeErr := httputil.WriteJSONResponse(w, http.StatusInternalServerError, StatusResponse{
		Status: "error",
		Details: &StatusResponseDetails{
			Code:    http.StatusInternalServerError,
			Message: err.Error(),
		},
	})
	if writeErr != nil {
		// TODO(bobbyrullo): replace with logging from new logging pkg,
		// once it lands.
		log.Printf("Failed to write JSON response: %v", err)
	}
}
Example #3
0
func TestHandlerFunc(t *testing.T) {
	for i, test := range []struct {
		checker         Checker
		method          string
		expectedStatus  string
		expectedCode    int
		expectedMessage string
	}{
		{
			Checker{
				Checks: []Checkable{
					boolChecker(true),
				},
			},
			"GET",
			"ok",
			http.StatusOK,
			"",
		},

		// Wrong method.
		{
			Checker{
				Checks: []Checkable{
					boolChecker(true),
				},
			},
			"POST",
			"",
			http.StatusMethodNotAllowed,
			"GET only acceptable method",
		},

		// Health check fails.
		{
			Checker{
				Checks: []Checkable{
					boolChecker(false),
				},
			},
			"GET",
			"error",
			http.StatusInternalServerError,
			"Unhealthy",
		},

		// Health check fails, with overridden ErrorHandler.
		{
			Checker{
				Checks: []Checkable{
					boolChecker(false),
				},
				UnhealthyHandler: func(w http.ResponseWriter, r *http.Request, err error) {
					httputil.WriteJSONResponse(w,
						http.StatusInternalServerError, StatusResponse{
							Status: "error",
							Details: &StatusResponseDetails{
								Code:    http.StatusInternalServerError,
								Message: "Override!",
							},
						})
				},
			},
			"GET",
			"error",
			http.StatusInternalServerError,
			"Override!",
		},

		// Health check succeeds, with overridden SuccessHandler.
		{
			Checker{
				Checks: []Checkable{
					boolChecker(true),
				},
				HealthyHandler: func(w http.ResponseWriter, r *http.Request) {
					httputil.WriteJSONResponse(w,
						http.StatusOK, StatusResponse{
							Status: "okey-dokey",
						})
				},
			},
			"GET",
			"okey-dokey",
			http.StatusOK,
			"",
		},
	} {
		w := httptest.NewRecorder()
		r := &http.Request{}
		r.Method = test.method
		test.checker.ServeHTTP(w, r)
		if w.Code != test.expectedCode {
			t.Errorf("case %d: w.code == %v, want %v", i, w.Code, test.expectedCode)
		}

		if test.expectedStatus == "" {
			// This is to handle the wrong-method case, when the
			// body of the response is empty.
			continue
		}

		statusMap := make(map[string]interface{})
		err := json.Unmarshal(w.Body.Bytes(), &statusMap)
		if err != nil {
			t.Fatalf("case %d: failed to Unmarshal response body: %v", i, err)
		}

		status, ok := statusMap["status"].(string)
		if !ok {
			t.Errorf("case %d: status not present or not a string in json: %q", i, w.Body.Bytes())
		}
		if status != test.expectedStatus {
			t.Errorf("case %d: status == %v, want %v", i, status, test.expectedStatus)
		}

		detailMap, ok := statusMap["details"].(map[string]interface{})
		if test.expectedMessage != "" {
			if !ok {
				t.Fatalf("case %d: could not find/unmarshal detailMap", i)
			}
			message, ok := detailMap["message"].(string)
			if !ok {
				t.Fatalf("case %d: message not present or not a string in json: %q",
					i, w.Body.Bytes())
			}
			if message != test.expectedMessage {
				t.Errorf("case %d: message == %v, want %v", i, message, test.expectedMessage)
			}

			code, ok := detailMap["code"].(float64)
			if !ok {
				t.Fatalf("case %d: code not present or not an int in json: %q",
					i, w.Body.Bytes())
			}
			if int(code) != test.expectedCode {
				t.Errorf("case %d: code == %v, want %v", i, code, test.expectedCode)
			}

		} else {
			if ok {
				t.Errorf("case %d: unwanted detailMap present: %q", i, detailMap)
			}
		}

	}
}