feat: add IM service health and metrics endpoints
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
immetrics "github.com/tinode/chat/server/metrics"
|
||||
"github.com/tinode/chat/server/store"
|
||||
"github.com/tinode/chat/server/store/mock_store"
|
||||
)
|
||||
|
||||
func TestServeHealthzOK(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
mockStore := mock_store.NewMockPersistentStorageInterface(ctrl)
|
||||
oldStore := store.Store
|
||||
store.Store = mockStore
|
||||
t.Cleanup(func() { store.Store = oldStore })
|
||||
mockStore.EXPECT().HealthCheck(gomock.Any()).Return(nil)
|
||||
|
||||
wrt := httptest.NewRecorder()
|
||||
serveHealthz(wrt, httptest.NewRequest(http.MethodGet, "/healthz", nil))
|
||||
|
||||
if wrt.Code != http.StatusOK {
|
||||
t.Fatalf("unexpected status %d body=%s", wrt.Code, wrt.Body.String())
|
||||
}
|
||||
if body := wrt.Body.String(); !strings.Contains(body, `"status":"ok"`) || !strings.Contains(body, `"mysql":"ok"`) {
|
||||
t.Fatalf("unexpected body %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeHealthzError(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
mockStore := mock_store.NewMockPersistentStorageInterface(ctrl)
|
||||
oldStore := store.Store
|
||||
store.Store = mockStore
|
||||
t.Cleanup(func() { store.Store = oldStore })
|
||||
mockStore.EXPECT().HealthCheck(gomock.Any()).Return(errors.New("dial timeout"))
|
||||
|
||||
wrt := httptest.NewRecorder()
|
||||
serveHealthz(wrt, httptest.NewRequest(http.MethodGet, "/healthz", nil))
|
||||
|
||||
if wrt.Code != http.StatusServiceUnavailable {
|
||||
t.Fatalf("unexpected status %d body=%s", wrt.Code, wrt.Body.String())
|
||||
}
|
||||
if body := wrt.Body.String(); !strings.Contains(body, `"status":"error"`) || !strings.Contains(body, `"mysql":"dial timeout"`) {
|
||||
t.Fatalf("unexpected body %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeMetricsIncludesWSConnections(t *testing.T) {
|
||||
wrt := httptest.NewRecorder()
|
||||
serveMetrics(wrt, httptest.NewRequest(http.MethodGet, "/metrics", nil))
|
||||
|
||||
if wrt.Code != http.StatusOK {
|
||||
t.Fatalf("unexpected status %d body=%s", wrt.Code, wrt.Body.String())
|
||||
}
|
||||
body := wrt.Body.String()
|
||||
if !strings.Contains(body, "# TYPE ws_connections_active gauge") || !strings.Contains(body, "ws_connections_active ") {
|
||||
t.Fatalf("unexpected body %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonitorHTTPRecordsRequestMetrics(t *testing.T) {
|
||||
handler := monitorHTTP(http.HandlerFunc(func(wrt http.ResponseWriter, req *http.Request) {
|
||||
wrt.WriteHeader(http.StatusCreated)
|
||||
}))
|
||||
|
||||
handler.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodPost, "/v1/im/users/1234567890123456789/profile", nil))
|
||||
wrt := httptest.NewRecorder()
|
||||
serveMetrics(wrt, httptest.NewRequest(http.MethodGet, "/metrics", nil))
|
||||
|
||||
body := wrt.Body.String()
|
||||
if !strings.Contains(body, `http_requests_total{method="POST",path="/v1/im/users/{id}/profile",status="201"} 1`) {
|
||||
t.Fatalf("request counter was not exported: %s", body)
|
||||
}
|
||||
if !strings.Contains(body, `http_request_duration_seconds_bucket{method="POST",path="/v1/im/users/{id}/profile",status="201"`) {
|
||||
t.Fatalf("request duration was not exported: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeMetricsIncludesDBQueryDuration(t *testing.T) {
|
||||
immetrics.ObserveDB("mysql", "query", time.Now().Add(-time.Millisecond), nil)
|
||||
|
||||
wrt := httptest.NewRecorder()
|
||||
serveMetrics(wrt, httptest.NewRequest(http.MethodGet, "/metrics", nil))
|
||||
|
||||
body := wrt.Body.String()
|
||||
if !strings.Contains(body, `db_query_duration_seconds_bucket{driver="mysql",operation="query",status="ok"`) {
|
||||
t.Fatalf("db query duration was not exported: %s", body)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user