package metrics import ( "testing" "time" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestRecordDBQuery(t *testing.T) { start := time.Now() time.Sleep(10 * time.Millisecond) duration := time.Since(start) RecordDBQuery("SELECT", "users", duration) // Vérifier que les métriques ont été enregistrées registry := prometheus.DefaultRegisterer.(*prometheus.Registry) metricFamilies, err := registry.Gather() require.NoError(t, err) foundQueriesTotal := false foundDuration := false for _, mf := range metricFamilies { if *mf.Name == "veza_db_queries_total" { foundQueriesTotal = true assert.Greater(t, len(mf.Metric), 0) } if *mf.Name == "veza_db_query_duration_seconds" { foundDuration = true assert.Greater(t, len(mf.Metric), 0) } } assert.True(t, foundQueriesTotal, "veza_db_queries_total metric should exist") assert.True(t, foundDuration, "veza_db_query_duration_seconds metric should exist") } func TestRecordDBQuery_MultipleOperations(t *testing.T) { operations := []struct { operation string table string duration time.Duration }{ {"SELECT", "users", 10 * time.Millisecond}, {"INSERT", "users", 15 * time.Millisecond}, {"UPDATE", "users", 12 * time.Millisecond}, {"DELETE", "users", 8 * time.Millisecond}, {"SELECT", "tracks", 20 * time.Millisecond}, } for _, op := range operations { RecordDBQuery(op.operation, op.table, op.duration) } // Vérifier que toutes les métriques sont enregistrées registry := prometheus.DefaultRegisterer.(*prometheus.Registry) metricFamilies, err := registry.Gather() require.NoError(t, err) for _, mf := range metricFamilies { if *mf.Name == "veza_db_queries_total" { // Au moins 5 requêtes devraient être comptées assert.GreaterOrEqual(t, len(mf.Metric), 1) } } } func TestUpdateDBConnections(t *testing.T) { UpdateDBConnections(10, 5, 5) // Vérifier que les métriques ont été mises à jour registry := prometheus.DefaultRegisterer.(*prometheus.Registry) metricFamilies, err := registry.Gather() require.NoError(t, err) foundConnections := false openValue := float64(0) idleValue := float64(0) inUseValue := float64(0) for _, mf := range metricFamilies { if *mf.Name == "veza_db_connections" { foundConnections = true for _, metric := range mf.Metric { if metric.Gauge != nil { for _, label := range metric.Label { switch *label.Value { case "open": openValue = *metric.Gauge.Value case "idle": idleValue = *metric.Gauge.Value case "in_use": inUseValue = *metric.Gauge.Value } } } } } } assert.True(t, foundConnections, "veza_db_connections metric should exist") assert.Equal(t, float64(10), openValue, "open connections should be 10") assert.Equal(t, float64(5), idleValue, "idle connections should be 5") assert.Equal(t, float64(5), inUseValue, "in_use connections should be 5") } func TestUpdateDBConnections_ZeroValues(t *testing.T) { UpdateDBConnections(0, 0, 0) registry := prometheus.DefaultRegisterer.(*prometheus.Registry) metricFamilies, err := registry.Gather() require.NoError(t, err) for _, mf := range metricFamilies { if *mf.Name == "veza_db_connections" { for _, metric := range mf.Metric { if metric.Gauge != nil { for _, label := range metric.Label { if *label.Value == "open" { assert.Equal(t, float64(0), *metric.Gauge.Value) } } } } } } } func TestUpdateDBConnections_AllStates(t *testing.T) { testCases := []struct { open int idle int inUse int }{ {10, 5, 5}, {25, 20, 5}, {1, 0, 1}, {100, 90, 10}, } for _, tc := range testCases { t.Run("", func(t *testing.T) { UpdateDBConnections(tc.open, tc.idle, tc.inUse) registry := prometheus.DefaultRegisterer.(*prometheus.Registry) metricFamilies, err := registry.Gather() require.NoError(t, err) for _, mf := range metricFamilies { if *mf.Name == "veza_db_connections" { values := make(map[string]float64) for _, metric := range mf.Metric { if metric.Gauge != nil { for _, label := range metric.Label { values[*label.Value] = *metric.Gauge.Value } } } assert.Equal(t, float64(tc.open), values["open"]) assert.Equal(t, float64(tc.idle), values["idle"]) assert.Equal(t, float64(tc.inUse), values["in_use"]) } } }) } } func TestRecordDBQuery_HistogramBuckets(t *testing.T) { // Tester avec différentes durées durations := []time.Duration{ 1 * time.Millisecond, 10 * time.Millisecond, 50 * time.Millisecond, 100 * time.Millisecond, 500 * time.Millisecond, 1 * time.Second, } for _, duration := range durations { RecordDBQuery("SELECT", "test", duration) } // Vérifier que l'histogramme est correctement configuré registry := prometheus.DefaultRegisterer.(*prometheus.Registry) metricFamilies, err := registry.Gather() require.NoError(t, err) for _, mf := range metricFamilies { if *mf.Name == "veza_db_query_duration_seconds" { assert.Equal(t, dto.MetricType_HISTOGRAM, *mf.Type) assert.Greater(t, len(mf.Metric), 0) } } } func TestRecordDBQuery_UnknownTable(t *testing.T) { // Tester avec table "unknown" RecordDBQuery("SELECT", "unknown", 10*time.Millisecond) registry := prometheus.DefaultRegisterer.(*prometheus.Registry) metricFamilies, err := registry.Gather() require.NoError(t, err) for _, mf := range metricFamilies { if *mf.Name == "veza_db_queries_total" { for _, metric := range mf.Metric { for _, label := range metric.Label { if *label.Name == "table" && *label.Value == "unknown" { assert.True(t, true, "Should record queries with unknown table") } } } } } }