mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
``` git ls-files \*.js \*.go \ | xargs sed -i '1i // SPDX-FileCopyrightText: 2022 Free Mobile\n// SPDX-License-Identifier: AGPL-3.0-only\n' git ls-files \*.vue \ | xargs sed -i '1i <!-- SPDX-FileCopyrightText: 2022 Free Mobile -->\n<!-- SPDX-License-Identifier: AGPL-3.0-only -->\n' ```
159 lines
4.7 KiB
Go
159 lines
4.7 KiB
Go
// SPDX-FileCopyrightText: 2022 Free Mobile
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
package reporter_test
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"akvorado/common/helpers"
|
|
"akvorado/common/reporter"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func testHealthchecks(ctx context.Context, t *testing.T, r *reporter.Reporter, expected reporter.MultipleHealthcheckResults) {
|
|
t.Helper()
|
|
got := r.RunHealthchecks(ctx)
|
|
if diff := helpers.Diff(got, expected); diff != "" {
|
|
t.Errorf("RunHealthchecks() (-got, +want):\n%s", diff)
|
|
}
|
|
}
|
|
|
|
func TestEmptyHealthcheck(t *testing.T) {
|
|
r := reporter.NewMock(t)
|
|
testHealthchecks(context.Background(), t, r,
|
|
reporter.MultipleHealthcheckResults{
|
|
Status: reporter.HealthcheckOK,
|
|
Details: map[string]reporter.HealthcheckResult{},
|
|
})
|
|
}
|
|
|
|
func TestOneHealthcheck(t *testing.T) {
|
|
r := reporter.NewMock(t)
|
|
r.RegisterHealthcheck("hc1", func(ctx context.Context) reporter.HealthcheckResult {
|
|
return reporter.HealthcheckResult{reporter.HealthcheckOK, "all well"}
|
|
})
|
|
testHealthchecks(context.Background(), t, r,
|
|
reporter.MultipleHealthcheckResults{
|
|
Status: reporter.HealthcheckOK,
|
|
Details: map[string]reporter.HealthcheckResult{
|
|
"hc1": {reporter.HealthcheckOK, "all well"},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestFailingHealthcheck(t *testing.T) {
|
|
r := reporter.NewMock(t)
|
|
r.RegisterHealthcheck("hc1", func(ctx context.Context) reporter.HealthcheckResult {
|
|
return reporter.HealthcheckResult{reporter.HealthcheckOK, "all well"}
|
|
})
|
|
r.RegisterHealthcheck("hc2", func(ctx context.Context) reporter.HealthcheckResult {
|
|
return reporter.HealthcheckResult{reporter.HealthcheckError, "not so good"}
|
|
})
|
|
testHealthchecks(context.Background(), t, r,
|
|
reporter.MultipleHealthcheckResults{
|
|
Status: reporter.HealthcheckError,
|
|
Details: map[string]reporter.HealthcheckResult{
|
|
"hc1": {reporter.HealthcheckOK, "all well"},
|
|
"hc2": {reporter.HealthcheckError, "not so good"},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestHealthcheckCancelContext(t *testing.T) {
|
|
r := reporter.NewMock(t)
|
|
r.RegisterHealthcheck("hc1", func(ctx context.Context) reporter.HealthcheckResult {
|
|
return reporter.HealthcheckResult{reporter.HealthcheckOK, "all well"}
|
|
})
|
|
r.RegisterHealthcheck("hc2", func(ctx context.Context) reporter.HealthcheckResult {
|
|
select {
|
|
case <-ctx.Done():
|
|
return reporter.HealthcheckResult{reporter.HealthcheckError, "I am late, sorry"}
|
|
}
|
|
})
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
go func() {
|
|
time.Sleep(10 * time.Millisecond)
|
|
cancel()
|
|
}()
|
|
testHealthchecks(ctx, t, r,
|
|
reporter.MultipleHealthcheckResults{
|
|
Status: reporter.HealthcheckError,
|
|
Details: map[string]reporter.HealthcheckResult{
|
|
"hc1": {reporter.HealthcheckOK, "all well"},
|
|
"hc2": {reporter.HealthcheckError, "timeout during check"},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestChannelHealthcheck(t *testing.T) {
|
|
contact := make(chan reporter.ChannelHealthcheckFunc)
|
|
go func() {
|
|
select {
|
|
case f := <-contact:
|
|
f(reporter.HealthcheckOK, "all well, thank you!")
|
|
case <-time.After(50 * time.Millisecond):
|
|
}
|
|
}()
|
|
|
|
r := reporter.NewMock(t)
|
|
r.RegisterHealthcheck("hc1", reporter.ChannelHealthcheck(context.Background(), contact))
|
|
testHealthchecks(context.Background(), t, r,
|
|
reporter.MultipleHealthcheckResults{
|
|
Status: reporter.HealthcheckOK,
|
|
Details: map[string]reporter.HealthcheckResult{
|
|
"hc1": {reporter.HealthcheckOK, "all well, thank you!"},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestHealthcheckHTTPHandler(t *testing.T) {
|
|
r := reporter.NewMock(t)
|
|
r.RegisterHealthcheck("hc1", func(ctx context.Context) reporter.HealthcheckResult {
|
|
return reporter.HealthcheckResult{reporter.HealthcheckOK, "all well"}
|
|
})
|
|
r.RegisterHealthcheck("hc2", func(ctx context.Context) reporter.HealthcheckResult {
|
|
return reporter.HealthcheckResult{reporter.HealthcheckError, "trying to be better"}
|
|
})
|
|
|
|
req := httptest.NewRequest("GET", "/api/v0/healthcheck", nil)
|
|
w := httptest.NewRecorder()
|
|
ginRouter := gin.Default()
|
|
ginRouter.GET("/api/v0/healthcheck", r.HealthcheckHTTPHandler)
|
|
ginRouter.ServeHTTP(w, req)
|
|
if w.Code != http.StatusServiceUnavailable {
|
|
t.Errorf("GET /api/v0/healthcheck status code, got %d, expected %d",
|
|
w.Code, http.StatusServiceUnavailable)
|
|
}
|
|
|
|
reader := bufio.NewReader(w.Body)
|
|
decoder := json.NewDecoder(reader)
|
|
var got map[string]interface{}
|
|
if err := decoder.Decode(&got); err != nil {
|
|
t.Fatalf("GET /api/v0/healthcheck error:\n%+v", err)
|
|
}
|
|
expected := map[string]interface{}{
|
|
"status": "error",
|
|
"details": map[string]interface{}{
|
|
"hc1": map[string]string{
|
|
"status": "ok",
|
|
"reason": "all well",
|
|
},
|
|
"hc2": map[string]string{
|
|
"status": "error",
|
|
"reason": "trying to be better",
|
|
},
|
|
},
|
|
}
|
|
if diff := helpers.Diff(got, expected); diff != "" {
|
|
t.Fatalf("GET /api/v0/healthcheck (-got, +want):\n%s", diff)
|
|
}
|
|
}
|