Skip to content

Commit 8ddfd26

Browse files
authored
Add health-check test
(cherry picked from commit 84f5115)
1 parent 12c2864 commit 8ddfd26

File tree

2 files changed

+49
-21
lines changed

2 files changed

+49
-21
lines changed

routers/web/healthcheck/check.go

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,36 @@ import (
1919
type status string
2020

2121
const (
22-
// pass healthy (acceptable aliases: "ok" to support Node's Terminus and "up" for Java's SpringBoot)
22+
// Pass healthy (acceptable aliases: "ok" to support Node's Terminus and "up" for Java's SpringBoot)
2323
// fail unhealthy (acceptable aliases: "error" to support Node's Terminus and "down" for Java's SpringBoot), and
2424
// warn healthy, with some concerns.
2525
//
2626
// ref https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check#section-3.1
2727
// status: (required) indicates whether the service status is acceptable
2828
// or not. API publishers SHOULD use following values for the field:
2929
// The value of the status field is case-insensitive and is tightly
30-
// related with the HTTP response code returned by the health endpoint.
31-
// For "pass" status, HTTP response code in the 2xx-3xx range MUST be
32-
// used. For "fail" status, HTTP response code in the 4xx-5xx range
30+
// related with the HTTP Response code returned by the health endpoint.
31+
// For "pass" status, HTTP Response code in the 2xx-3xx range MUST be
32+
// used. For "fail" status, HTTP Response code in the 4xx-5xx range
3333
// MUST be used. In case of the "warn" status, endpoints MUST return
3434
// HTTP status in the 2xx-3xx range, and additional information SHOULD
35-
// be provided, utilizing optional fields of the response.
36-
pass status = "pass"
37-
fail status = "fail"
35+
// be provided, utilizing optional fields of the Response.
36+
Pass status = "pass"
37+
Fail status = "fail"
3838
warn status = "warn"
3939
)
4040

4141
func (s status) ToHTTPStatus() int {
42-
if s == pass || s == warn {
42+
if s == Pass || s == warn {
4343
return http.StatusOK
4444
}
4545
return http.StatusFailedDependency
4646
}
4747

4848
type checks map[string][]componentStatus
4949

50-
// response is the data returned by the health endpoint, which will be marshaled to JSON format
51-
type response struct {
50+
// Response is the data returned by the health endpoint, which will be marshaled to JSON format
51+
type Response struct {
5252
Status status `json:"status"`
5353
Description string `json:"description"` // a human-friendly description of the service
5454
Checks checks `json:"checks,omitempty"` // The Checks Object, should be omitted on installation route
@@ -65,8 +65,8 @@ type componentStatus struct {
6565

6666
// Check is the health check API handler
6767
func Check(w http.ResponseWriter, r *http.Request) {
68-
rsp := response{
69-
Status: pass,
68+
rsp := Response{
69+
Status: Pass,
7070
Description: setting.AppName,
7171
Checks: make(checks),
7272
}
@@ -77,8 +77,8 @@ func Check(w http.ResponseWriter, r *http.Request) {
7777
statuses = append(statuses, checkCache(rsp.Checks))
7878
}
7979
for _, s := range statuses {
80-
if s != pass {
81-
rsp.Status = fail
80+
if s != Pass {
81+
rsp.Status = Fail
8282
break
8383
}
8484
}
@@ -94,22 +94,22 @@ func Check(w http.ResponseWriter, r *http.Request) {
9494
func checkDatabase(ctx context.Context, checks checks) status {
9595
st := componentStatus{}
9696
if err := db.GetEngine(ctx).Ping(); err != nil {
97-
st.Status = fail
97+
st.Status = Fail
9898
st.Time = getCheckTime()
9999
log.Error("database ping failed with error: %v", err)
100100
} else {
101-
st.Status = pass
101+
st.Status = Pass
102102
st.Time = getCheckTime()
103103
}
104104

105-
if setting.Database.Type.IsSQLite3() && st.Status == pass {
105+
if setting.Database.Type.IsSQLite3() && st.Status == Pass {
106106
if !setting.EnableSQLite3 {
107-
st.Status = fail
107+
st.Status = Fail
108108
st.Time = getCheckTime()
109109
log.Error("SQLite3 health check failed with error: %v", "this Forgejo binary is built without SQLite3 enabled")
110110
} else {
111111
if _, err := os.Stat(setting.Database.Path); err != nil {
112-
st.Status = fail
112+
st.Status = Fail
113113
st.Time = getCheckTime()
114114
log.Error("SQLite3 file exists check failed with error: %v", err)
115115
}
@@ -124,11 +124,11 @@ func checkDatabase(ctx context.Context, checks checks) status {
124124
func checkCache(checks checks) status {
125125
st := componentStatus{}
126126
if err := cache.GetCache().Ping(); err != nil {
127-
st.Status = fail
127+
st.Status = Fail
128128
st.Time = getCheckTime()
129129
log.Error("cache ping failed with error: %v", err)
130130
} else {
131-
st.Status = pass
131+
st.Status = Pass
132132
st.Time = getCheckTime()
133133
}
134134
checks["cache:ping"] = []componentStatus{st}

tests/integration/api_health_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package integration
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"code.gitea.io/gitea/modules/setting"
8+
"code.gitea.io/gitea/routers/web/healthcheck"
9+
"code.gitea.io/gitea/tests"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestApiHeatlhCheck(t *testing.T) {
15+
defer tests.PrepareTestEnv(t)()
16+
t.Run("Test health-check pass", func(t *testing.T) {
17+
defer tests.PrintCurrentTest(t)()
18+
19+
req := NewRequest(t, "GET", "/api/healthz")
20+
resp := MakeRequest(t, req, http.StatusOK)
21+
assert.Contains(t, resp.Header().Values("Cache-Control"), "no-store")
22+
23+
var status healthcheck.Response
24+
DecodeJSON(t, resp, &status)
25+
assert.Equal(t, healthcheck.Pass, status.Status)
26+
assert.Equal(t, setting.AppName, status.Description)
27+
})
28+
}

0 commit comments

Comments
 (0)