2020-10-21 04:06:19 -05:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2023-01-30 02:18:26 -06:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2023-01-18 09:01:25 -06:00
|
|
|
"github.com/grafana/grafana/pkg/infra/db/dbtest"
|
2020-10-21 04:06:19 -05:00
|
|
|
"github.com/grafana/grafana/pkg/infra/localcache"
|
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2021-10-11 07:30:59 -05:00
|
|
|
"github.com/grafana/grafana/pkg/web"
|
2020-10-21 04:06:19 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestHealthAPI_Version(t *testing.T) {
|
2021-03-10 05:41:29 -06:00
|
|
|
m, _ := setupHealthAPITestEnvironment(t, func(cfg *setting.Cfg) {
|
|
|
|
cfg.BuildVersion = "7.4.0"
|
|
|
|
cfg.BuildCommit = "59906ab1bf"
|
|
|
|
})
|
2020-10-21 04:06:19 -05:00
|
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/health", nil)
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(rec, req)
|
|
|
|
|
|
|
|
require.Equal(t, 200, rec.Code)
|
|
|
|
expectedBody := `
|
|
|
|
{
|
|
|
|
"database": "ok",
|
|
|
|
"version": "7.4.0",
|
|
|
|
"commit": "59906ab1bf"
|
|
|
|
}
|
|
|
|
`
|
|
|
|
require.JSONEq(t, expectedBody, rec.Body.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHealthAPI_AnonymousHideVersion(t *testing.T) {
|
|
|
|
m, hs := setupHealthAPITestEnvironment(t)
|
|
|
|
hs.Cfg.AnonymousHideVersion = true
|
|
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/health", nil)
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(rec, req)
|
|
|
|
|
|
|
|
require.Equal(t, 200, rec.Code)
|
|
|
|
expectedBody := `
|
|
|
|
{
|
|
|
|
"database": "ok"
|
|
|
|
}
|
|
|
|
`
|
|
|
|
require.JSONEq(t, expectedBody, rec.Body.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHealthAPI_DatabaseHealthy(t *testing.T) {
|
|
|
|
const cacheKey = "db-healthy"
|
|
|
|
|
|
|
|
m, hs := setupHealthAPITestEnvironment(t)
|
|
|
|
hs.Cfg.AnonymousHideVersion = true
|
|
|
|
|
|
|
|
healthy, found := hs.CacheService.Get(cacheKey)
|
|
|
|
require.False(t, found)
|
|
|
|
require.Nil(t, healthy)
|
|
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/health", nil)
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(rec, req)
|
|
|
|
|
|
|
|
require.Equal(t, 200, rec.Code)
|
|
|
|
expectedBody := `
|
|
|
|
{
|
|
|
|
"database": "ok"
|
|
|
|
}
|
|
|
|
`
|
|
|
|
require.JSONEq(t, expectedBody, rec.Body.String())
|
|
|
|
|
|
|
|
healthy, found = hs.CacheService.Get(cacheKey)
|
|
|
|
require.True(t, found)
|
|
|
|
require.True(t, healthy.(bool))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHealthAPI_DatabaseUnhealthy(t *testing.T) {
|
|
|
|
const cacheKey = "db-healthy"
|
|
|
|
|
|
|
|
m, hs := setupHealthAPITestEnvironment(t)
|
|
|
|
hs.Cfg.AnonymousHideVersion = true
|
2023-01-18 09:01:25 -06:00
|
|
|
hs.SQLStore.(*dbtest.FakeDB).ExpectedError = errors.New("bad")
|
2020-10-21 04:06:19 -05:00
|
|
|
|
|
|
|
healthy, found := hs.CacheService.Get(cacheKey)
|
|
|
|
require.False(t, found)
|
|
|
|
require.Nil(t, healthy)
|
|
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/health", nil)
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(rec, req)
|
|
|
|
|
|
|
|
require.Equal(t, 503, rec.Code)
|
|
|
|
expectedBody := `
|
|
|
|
{
|
|
|
|
"database": "failing"
|
|
|
|
}
|
|
|
|
`
|
|
|
|
require.JSONEq(t, expectedBody, rec.Body.String())
|
|
|
|
|
|
|
|
healthy, found = hs.CacheService.Get(cacheKey)
|
|
|
|
require.True(t, found)
|
|
|
|
require.False(t, healthy.(bool))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHealthAPI_DatabaseHealthCached(t *testing.T) {
|
|
|
|
const cacheKey = "db-healthy"
|
|
|
|
|
|
|
|
m, hs := setupHealthAPITestEnvironment(t)
|
|
|
|
hs.Cfg.AnonymousHideVersion = true
|
|
|
|
|
|
|
|
// Mock unhealthy database in cache.
|
|
|
|
hs.CacheService.Set(cacheKey, false, 5*time.Minute)
|
|
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/health", nil)
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(rec, req)
|
|
|
|
|
|
|
|
require.Equal(t, 503, rec.Code)
|
|
|
|
expectedBody := `
|
|
|
|
{
|
|
|
|
"database": "failing"
|
|
|
|
}
|
|
|
|
`
|
|
|
|
require.JSONEq(t, expectedBody, rec.Body.String())
|
|
|
|
|
|
|
|
// Purge cache and redo request.
|
|
|
|
hs.CacheService.Delete(cacheKey)
|
|
|
|
rec = httptest.NewRecorder()
|
|
|
|
m.ServeHTTP(rec, req)
|
|
|
|
|
|
|
|
require.Equal(t, 200, rec.Code)
|
|
|
|
expectedBody = `
|
|
|
|
{
|
|
|
|
"database": "ok"
|
|
|
|
}
|
|
|
|
`
|
|
|
|
require.JSONEq(t, expectedBody, rec.Body.String())
|
|
|
|
|
|
|
|
healthy, found := hs.CacheService.Get(cacheKey)
|
|
|
|
require.True(t, found)
|
|
|
|
require.True(t, healthy.(bool))
|
|
|
|
}
|
|
|
|
|
2021-10-11 07:30:59 -05:00
|
|
|
func setupHealthAPITestEnvironment(t *testing.T, cbs ...func(*setting.Cfg)) (*web.Mux, *HTTPServer) {
|
2020-10-21 04:06:19 -05:00
|
|
|
t.Helper()
|
|
|
|
|
2021-10-11 07:30:59 -05:00
|
|
|
m := web.New()
|
2021-03-10 05:41:29 -06:00
|
|
|
cfg := setting.NewCfg()
|
|
|
|
for _, cb := range cbs {
|
|
|
|
cb(cfg)
|
|
|
|
}
|
2020-10-21 04:06:19 -05:00
|
|
|
hs := &HTTPServer{
|
|
|
|
CacheService: localcache.New(5*time.Minute, 10*time.Minute),
|
2021-03-10 05:41:29 -06:00
|
|
|
Cfg: cfg,
|
2023-01-18 09:01:25 -06:00
|
|
|
SQLStore: dbtest.NewFakeDB(),
|
2020-10-21 04:06:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
m.Get("/api/health", hs.apiHealthHandler)
|
|
|
|
return m, hs
|
|
|
|
}
|