mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-11 17:10:40 +02:00
* telemetry: sync the server module to go 1.26 The root module moved to go 1.26 but the telemetry server module, which replaces seaweedfs with the repo root, stayed on 1.25.8, so go refuses to build or test it until the directive catches up. * telemetry: confirm a cluster after a week of reports, not two days Two days of history still lets recurring CI and demo clusters into the confirmed fleet: anything torn down and rebuilt across a UTC midnight counts. Requiring seven distinct UTC days keeps the fleet charts and the version/OS distributions to clusters that actually stay up; real clusters qualify after their first week, and the fallback to all active clusters while none is confirmed is unchanged.
164 lines
5.6 KiB
Go
164 lines
5.6 KiB
Go
package storage
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
// Every cluster counts towards every day it reported on, not just towards the
|
|
// one day it last reported on.
|
|
func TestGetMetricsSumsEachDay(t *testing.T) {
|
|
s := newPrometheusStorage(prometheus.NewRegistry())
|
|
|
|
// Reported every day of the window.
|
|
seedSamples(s, "daily", HistorySample{TotalDiskBytes: 300, VolumeServerCount: 3},
|
|
-9, -8, -7, -6, -5, -4, -3, -2, -1, 0)
|
|
// Stopped reporting past the active window: counts on its own days only.
|
|
seedSamples(s, "gone", HistorySample{TotalDiskBytes: 900, VolumeServerCount: 9},
|
|
-14, -13, -12, -11, -10, -9, -8)
|
|
|
|
metrics, err := s.GetMetrics(10)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if got := metrics["dates"].([]string); len(got) != 10 {
|
|
t.Fatalf("dates = %v, want 10 days", got)
|
|
}
|
|
if got := metrics["disk_usage"].([]uint64); !equal(got,
|
|
[]uint64{1200, 1200, 300, 300, 300, 300, 300, 300, 300, 300}) {
|
|
t.Errorf("disk_usage = %v, want the fleet total per day", got)
|
|
}
|
|
if got := metrics["server_counts"].([]int64); !equalInt64(got,
|
|
[]int64{12, 12, 3, 3, 3, 3, 3, 3, 3, 3}) {
|
|
t.Errorf("server_counts = %v, want the fleet total per day", got)
|
|
}
|
|
}
|
|
|
|
// A cluster that skipped a day keeps its size on that day rather than dipping
|
|
// the fleet total to zero and back.
|
|
func TestGetMetricsCarriesSkippedDaysForward(t *testing.T) {
|
|
s := newPrometheusStorage(prometheus.NewRegistry())
|
|
|
|
seedSamples(s, "gappy", HistorySample{TotalDiskBytes: 500, VolumeServerCount: 5},
|
|
-8, -7, -6, -5, -4, -3, -1)
|
|
|
|
metrics, err := s.GetMetrics(4)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := metrics["disk_usage"].([]uint64); !equal(got, []uint64{500, 500, 500, 500}) {
|
|
t.Errorf("disk_usage = %v, want the skipped days carried forward", got)
|
|
}
|
|
}
|
|
|
|
// The window starts at the oldest sample the server actually has, so a server
|
|
// with less history than the caller asked for does not report a fleet that grew
|
|
// out of nothing on its first day of data.
|
|
func TestGetMetricsWindowStartsAtOldestSample(t *testing.T) {
|
|
s := newPrometheusStorage(prometheus.NewRegistry())
|
|
seedSamples(s, "recent", HistorySample{TotalDiskBytes: 100, VolumeServerCount: 1},
|
|
-6, -5, -4, -3, -2, -1, 0)
|
|
|
|
metrics, err := s.GetMetrics(30)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := metrics["dates"].([]string); len(got) != 7 {
|
|
t.Errorf("dates = %v, want the 7 days with history, not 30", got)
|
|
}
|
|
if got := metrics["disk_usage"].([]uint64); !equal(got, []uint64{100, 100, 100, 100, 100, 100, 100}) {
|
|
t.Errorf("disk_usage = %v, want no leading zero days", got)
|
|
}
|
|
|
|
// History reaching past the requested window still clips to the window.
|
|
seedSamples(s, "old", HistorySample{TotalDiskBytes: 50, VolumeServerCount: 1},
|
|
-45, -44, -43, -42, -41, -40, -39)
|
|
metrics, err = s.GetMetrics(10)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := metrics["dates"].([]string); len(got) != 10 {
|
|
t.Errorf("dates = %v, want 10 days", got)
|
|
}
|
|
}
|
|
|
|
// /api/metrics is the fleet total that /api/cluster-sizes breaks down per
|
|
// cluster, so their last day has to add up to the same number.
|
|
func TestGetMetricsAgreesWithClusterSizes(t *testing.T) {
|
|
s := newPrometheusStorage(prometheus.NewRegistry())
|
|
seedSamples(s, "daily", HistorySample{TotalDiskBytes: 300, VolumeServerCount: 3},
|
|
-9, -8, -7, -6, -5, -4, -3, -2, -1, 0)
|
|
seedSamples(s, "lagging", HistorySample{TotalDiskBytes: 200, VolumeServerCount: 2},
|
|
-8, -7, -6, -5, -4, -3, -2)
|
|
seedSamples(s, "gone", HistorySample{TotalDiskBytes: 900, VolumeServerCount: 9},
|
|
-14, -13, -12, -11, -10, -9, -8)
|
|
|
|
metrics, err := s.GetMetrics(10)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
disk := metrics["disk_usage"].([]uint64)
|
|
sizes := s.GetClusterSizeSeries(10, 1) // limit forces the Other fold-in too
|
|
|
|
if got, want := disk[len(disk)-1], sizes.TotalDisk; got != want {
|
|
t.Errorf("metrics last day = %d, cluster sizes total = %d", got, want)
|
|
}
|
|
if len(disk) != len(sizes.Dates) {
|
|
t.Errorf("metrics has %d days, cluster sizes has %d", len(disk), len(sizes.Dates))
|
|
}
|
|
}
|
|
|
|
// Short-lived clusters -- a CI run, a docker-compose demo -- report once under a
|
|
// fresh raft topology id and never again. Held forward for the whole active
|
|
// window they would stack up into a fleet that grows every day, so they stay out
|
|
// of the totals until they are confirmed.
|
|
func TestGetMetricsExcludesUnconfirmedClusters(t *testing.T) {
|
|
s := newPrometheusStorage(prometheus.NewRegistry())
|
|
|
|
seedSamples(s, "real", HistorySample{TotalDiskBytes: 300, VolumeServerCount: 3},
|
|
-6, -5, -4, -3, -2, -1, 0)
|
|
for _, id := range []string{"ci-1", "ci-2", "ci-3"} {
|
|
seedSamples(s, id, HistorySample{TotalDiskBytes: 5, VolumeServerCount: 14}, -1)
|
|
}
|
|
|
|
metrics, err := s.GetMetrics(4)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := metrics["server_counts"].([]int64); !equalInt64(got, []int64{3, 3, 3, 3}) {
|
|
t.Errorf("server_counts = %v, want the confirmed cluster alone", got)
|
|
}
|
|
if got := metrics["disk_usage"].([]uint64); !equal(got, []uint64{300, 300, 300, 300}) {
|
|
t.Errorf("disk_usage = %v, want the confirmed cluster alone", got)
|
|
}
|
|
}
|
|
|
|
// Until any cluster has a week of history the charts fall back to every
|
|
// cluster, so a fresh server doesn't serve empty series.
|
|
func TestGetMetricsFallsBackWhenNoneConfirmed(t *testing.T) {
|
|
s := newPrometheusStorage(prometheus.NewRegistry())
|
|
seedSamples(s, "new", HistorySample{TotalDiskBytes: 100, VolumeServerCount: 2}, 0)
|
|
|
|
metrics, err := s.GetMetrics(7)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := metrics["server_counts"].([]int64); !equalInt64(got, []int64{2}) {
|
|
t.Errorf("server_counts = %v, want today's only cluster", got)
|
|
}
|
|
}
|
|
|
|
func equalInt64(a, b []int64) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if a[i] != b[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|