- Add prommetrics package tests (12 tests covering all metric functions) - Add routes/common_test.go with health check, readiness, liveness tests - Add SoraAdminView.spec.ts with 11 component tests
242 lines
6.2 KiB
Go
242 lines
6.2 KiB
Go
package routes
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestRegisterCommonRoutes(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
RegisterCommonRoutes(r)
|
|
|
|
// Test /health
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/health", nil)
|
|
r.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Test /live
|
|
w = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodGet, "/live", nil)
|
|
r.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Test /ready (no health checker set)
|
|
w = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodGet, "/ready", nil)
|
|
r.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Test /metrics
|
|
w = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodGet, "/metrics", nil)
|
|
r.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Test /setup/status
|
|
w = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodGet, "/setup/status", nil)
|
|
r.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var setupResp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &setupResp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, float64(0), setupResp["code"])
|
|
|
|
// Test POST /api/event_logging/batch
|
|
w = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodPost, "/api/event_logging/batch", nil)
|
|
r.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestHealthHandler_NoHealthChecker(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/health", nil)
|
|
|
|
healthHandler(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "ok", resp["status"])
|
|
|
|
components, ok := resp["components"].(map[string]interface{})
|
|
assert.True(t, ok)
|
|
db, ok := components["database"].(map[string]interface{})
|
|
assert.True(t, ok)
|
|
assert.Equal(t, "unknown", db["status"])
|
|
}
|
|
|
|
func TestReadinessHandler_NoHealthChecker(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/ready", nil)
|
|
|
|
readinessHandler(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "ready", resp["status"])
|
|
}
|
|
|
|
func TestLivenessHandler(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/live", nil)
|
|
|
|
livenessHandler(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "alive", resp["status"])
|
|
|
|
// Verify timestamp is valid
|
|
ts, ok := resp["timestamp"].(string)
|
|
assert.True(t, ok)
|
|
_, err = time.Parse(time.RFC3339, ts)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// mockHealthChecker implements HealthChecker for testing
|
|
type mockHealthChecker struct {
|
|
dbHealthy bool
|
|
redisHealthy bool
|
|
}
|
|
|
|
func (m *mockHealthChecker) CheckDatabase() bool { return m.dbHealthy }
|
|
func (m *mockHealthChecker) CheckRedis() bool { return m.redisHealthy }
|
|
|
|
func TestHealthHandler_WithHealthyChecker(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
// Reset the healthChecker for test
|
|
healthChecker = &mockHealthChecker{dbHealthy: true, redisHealthy: true}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/health", nil)
|
|
|
|
healthHandler(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "ok", resp["status"])
|
|
}
|
|
|
|
func TestHealthHandler_WithUnhealthyDB(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
healthChecker = &mockHealthChecker{dbHealthy: false, redisHealthy: true}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/health", nil)
|
|
|
|
healthHandler(c)
|
|
|
|
assert.Equal(t, http.StatusServiceUnavailable, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "degraded", resp["status"])
|
|
}
|
|
|
|
func TestHealthHandler_WithUnhealthyRedis(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
healthChecker = &mockHealthChecker{dbHealthy: true, redisHealthy: false}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/health", nil)
|
|
|
|
healthHandler(c)
|
|
|
|
assert.Equal(t, http.StatusServiceUnavailable, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "degraded", resp["status"])
|
|
}
|
|
|
|
func TestReadinessHandler_AllHealthy(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
healthChecker = &mockHealthChecker{dbHealthy: true, redisHealthy: true}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/ready", nil)
|
|
|
|
readinessHandler(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "ready", resp["status"])
|
|
}
|
|
|
|
func TestReadinessHandler_NotReady(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
healthChecker = &mockHealthChecker{dbHealthy: true, redisHealthy: false}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = httptest.NewRequest(http.MethodGet, "/ready", nil)
|
|
|
|
readinessHandler(c)
|
|
|
|
assert.Equal(t, http.StatusServiceUnavailable, w.Code)
|
|
|
|
var resp map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "not_ready", resp["status"])
|
|
}
|
|
|
|
func TestDelegatedMetricFunctions(t *testing.T) {
|
|
// These should not panic - they delegate to prommetrics package
|
|
RecordHTTPRequest("GET", "/test", 200, 100*time.Millisecond)
|
|
SetDBConnections(5, 3)
|
|
SetRedisConnections(10, 4)
|
|
SetActiveAccounts(50)
|
|
SetRequestQueueDepth(5)
|
|
SetOpsHealthScore(90)
|
|
SetErrorRate(0.1)
|
|
SetSuccessRate(0.9)
|
|
SetQPS(100.0)
|
|
SetTPS(500.0)
|
|
}
|