Очередь job получила lease и fencing, телеметрия и прогресс deploy сохраняются, ревизия пишет manifest входов. Обновление префиксов не переписывает неизменённый снимок, большие наборы идут через COPY, а устаревшая ревизия не попадает в deploy. Бандл ноды кэшируется, prune и постановка job больше не держат горячий путь. Co-authored-by: Cursor <[email protected]>
117 lines
3.6 KiB
Go
117 lines
3.6 KiB
Go
package observability
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
"evobgp/internal/store"
|
|
)
|
|
|
|
type failingMetricsBackend struct{ store.Backend }
|
|
|
|
func (failingMetricsBackend) ObserveStoreMetrics(context.Context) (int, int, int, map[string]int, error) {
|
|
return 0, 0, 0, nil, errors.New("database unavailable")
|
|
}
|
|
|
|
type storedMetricsBackend struct{ store.Backend }
|
|
|
|
func (storedMetricsBackend) ObserveStoreMetrics(context.Context) (int, int, int, map[string]int, error) {
|
|
return 12, 24, 1, map[string]int{"established": 1}, nil
|
|
}
|
|
|
|
type legacyStateBackend struct{ store.Backend }
|
|
|
|
func (legacyStateBackend) ObserveStoreMetrics(context.Context) (int, int, int, map[string]int, error) {
|
|
return 0, 0, 2, map[string]int{" Established ": 1, "established": 1}, nil
|
|
}
|
|
|
|
func TestStoreMetricsCollectionErrorOmitsAggregates(t *testing.T) {
|
|
metricsStore.Store(storeBackendHolder{backend: failingMetricsBackend{}})
|
|
registry := prometheus.NewRegistry()
|
|
if err := registry.Register(newMemoryStoreCollector()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
families, err := registry.Gather()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(families) != 1 || families[0].GetName() != "evobgp_store_metrics_collection_success" {
|
|
t.Fatalf("expected only collection status on error, got %v", families)
|
|
}
|
|
if got := families[0].Metric[0].Gauge.GetValue(); got != 0 {
|
|
t.Fatalf("collection status = %v, want 0", got)
|
|
}
|
|
}
|
|
|
|
func TestStoredRevisionMetricsDoNotClaimCurrentRoutes(t *testing.T) {
|
|
metricsStore.Store(storeBackendHolder{backend: storedMetricsBackend{}})
|
|
registry := prometheus.NewRegistry()
|
|
if err := registry.Register(newMemoryStoreCollector()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
families, err := registry.Gather()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
values := make(map[string]float64)
|
|
for _, family := range families {
|
|
if len(family.Metric) > 0 && family.Metric[0].Gauge != nil {
|
|
values[family.GetName()] = family.Metric[0].Gauge.GetValue()
|
|
}
|
|
}
|
|
if values["evobgp_stored_revision_materialized_prefixes_sum"] != 24 || values["evobgp_materialized_prefixes_sum"] != 24 {
|
|
t.Fatalf("stored revision and legacy sums must match: %v", values)
|
|
}
|
|
if values["evobgp_store_metrics_collection_success"] != 1 {
|
|
t.Fatalf("successful collection not reported: %v", values)
|
|
}
|
|
if _, ok := values["evobgp_current_routes"]; ok {
|
|
t.Fatal("historical revision sum must not be published as current routes")
|
|
}
|
|
}
|
|
|
|
func TestCanonicalPeerStateBoundsNewLabelValues(t *testing.T) {
|
|
if got := canonicalPeerState("Established"); got != "established" {
|
|
t.Fatalf("state = %q", got)
|
|
}
|
|
if got := canonicalPeerState("unexpected peer text"); got != "other" {
|
|
t.Fatalf("state = %q", got)
|
|
}
|
|
}
|
|
|
|
func TestLegacyPeerStateLabelPreservedWhileNewLabelIsCanonical(t *testing.T) {
|
|
metricsStore.Store(storeBackendHolder{backend: legacyStateBackend{}})
|
|
registry := prometheus.NewRegistry()
|
|
if err := registry.Register(newMemoryStoreCollector()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
families, err := registry.Gather()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
legacyRaw, newCanonical := false, false
|
|
for _, family := range families {
|
|
for _, metric := range family.Metric {
|
|
if len(metric.Label) != 1 {
|
|
continue
|
|
}
|
|
switch family.GetName() {
|
|
case "evobgp_bgp_peer_sessions":
|
|
if metric.Label[0].GetValue() == " Established " && metric.Gauge.GetValue() == 1 {
|
|
legacyRaw = true
|
|
}
|
|
case "evobgp_stored_bgp_peer_session_state":
|
|
if metric.Label[0].GetValue() == "established" && metric.Gauge.GetValue() == 2 {
|
|
newCanonical = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !legacyRaw || !newCanonical {
|
|
t.Fatalf("legacy raw state preserved=%v, new canonical state aggregated=%v", legacyRaw, newCanonical)
|
|
}
|
|
}
|