mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 22:06:38 +08:00
216 lines
6.5 KiB
Go
216 lines
6.5 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package observability
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/Rain-kl/Wavelet/internal/model"
|
|
)
|
|
|
|
func TestBuildTrafficTrendPointsFromHourlyBucketsByHour(t *testing.T) {
|
|
now := time.Date(2026, 7, 2, 15, 30, 0, 0, time.UTC)
|
|
hourly := []*model.OpenFlareTrafficHourly{
|
|
{
|
|
NodeID: "node-a",
|
|
Hour: now.Add(-2 * time.Hour).Truncate(time.Hour),
|
|
RequestCount: 12,
|
|
ErrorCount: 1,
|
|
UniqueVisitorCount: 4,
|
|
},
|
|
}
|
|
points := BuildTrafficTrendPointsFromHourly(now, hourly)
|
|
if len(points) != observabilityTrendBuckets {
|
|
t.Fatalf("BuildTrafficTrendPointsFromHourly() len = %d, want %d", len(points), observabilityTrendBuckets)
|
|
}
|
|
}
|
|
|
|
func TestBuildTrafficTrendPointsBucketsByHour(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.Date(2026, 6, 19, 17, 30, 0, 0, time.UTC)
|
|
reports := []*model.OpenFlareRequestReport{
|
|
{
|
|
NodeID: "node-a",
|
|
WindowStartedAt: now.Add(-3 * time.Hour),
|
|
WindowEndedAt: now.Add(-3*time.Hour + time.Minute),
|
|
RequestCount: 10,
|
|
ErrorCount: 1,
|
|
},
|
|
{
|
|
NodeID: "node-a",
|
|
WindowStartedAt: now.Add(-30 * time.Minute),
|
|
WindowEndedAt: now.Add(-29 * time.Minute),
|
|
RequestCount: 6,
|
|
ErrorCount: 0,
|
|
},
|
|
}
|
|
|
|
points := BuildTrafficTrendPoints(now, reports)
|
|
if len(points) != observabilityTrendBuckets {
|
|
t.Fatalf("BuildTrafficTrendPoints() len = %d, want %d", len(points), observabilityTrendBuckets)
|
|
}
|
|
|
|
var totalRequests int64
|
|
for _, point := range points {
|
|
totalRequests += point.RequestCount
|
|
}
|
|
if totalRequests != 16 {
|
|
t.Fatalf("total request_count = %d, want 16", totalRequests)
|
|
}
|
|
|
|
currentHour := points[len(points)-1]
|
|
if currentHour.RequestCount != 6 {
|
|
t.Fatalf("current hour request_count = %d, want 6", currentHour.RequestCount)
|
|
}
|
|
if currentHour.ErrorCount != 0 {
|
|
t.Fatalf("current hour error_count = %d, want 0", currentHour.ErrorCount)
|
|
}
|
|
}
|
|
|
|
func TestBuildMetricSnapshotViewsMergesOpenrestyObservation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
capturedAt := time.Date(2026, 6, 19, 12, 0, 0, 0, time.UTC)
|
|
snapshots := []*model.OpenFlareMetricSnapshot{
|
|
{
|
|
ID: 1,
|
|
NodeID: "node-a",
|
|
CapturedAt: capturedAt,
|
|
CPUUsagePercent: 12.5,
|
|
},
|
|
}
|
|
openrestyObs := []*model.OpenFlareNodeObservationOpenresty{
|
|
{
|
|
NodeID: "node-a",
|
|
CapturedAt: capturedAt.Add(5 * time.Second),
|
|
OpenrestyRxBytes: 4096,
|
|
OpenrestyTxBytes: 8192,
|
|
OpenrestyConnections: 7,
|
|
},
|
|
}
|
|
|
|
views := BuildMetricSnapshotViews(snapshots, openrestyObs)
|
|
if len(views) != 1 {
|
|
t.Fatalf("BuildMetricSnapshotViews() len = %d, want 1", len(views))
|
|
}
|
|
if views[0].OpenrestyRxBytes != 4096 {
|
|
t.Fatalf("OpenrestyRxBytes = %d, want 4096", views[0].OpenrestyRxBytes)
|
|
}
|
|
if views[0].OpenrestyTxBytes != 8192 {
|
|
t.Fatalf("OpenrestyTxBytes = %d, want 8192", views[0].OpenrestyTxBytes)
|
|
}
|
|
if views[0].OpenrestyConnections != 7 {
|
|
t.Fatalf("OpenrestyConnections = %d, want 7", views[0].OpenrestyConnections)
|
|
}
|
|
}
|
|
|
|
func TestLatestTrafficReportUsesLatestWindowEndedAt(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
older := &model.OpenFlareRequestReport{
|
|
WindowEndedAt: time.Date(2026, 6, 19, 10, 0, 0, 0, time.UTC),
|
|
RequestCount: 3,
|
|
}
|
|
newer := &model.OpenFlareRequestReport{
|
|
WindowEndedAt: time.Date(2026, 6, 19, 11, 0, 0, 0, time.UTC),
|
|
RequestCount: 9,
|
|
}
|
|
|
|
latest := latestTrafficReport([]*model.OpenFlareRequestReport{older, newer})
|
|
if latest == nil || latest.RequestCount != 9 {
|
|
t.Fatalf("latestTrafficReport() = %#v, want newer report with request_count 9", latest)
|
|
}
|
|
}
|
|
|
|
func TestBuildTrafficWindowSummaryNilWithoutReport(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if summary := buildTrafficWindowSummary(nil); summary != nil {
|
|
t.Fatalf("buildTrafficWindowSummary(nil) = %#v, want nil", summary)
|
|
}
|
|
}
|
|
|
|
func TestBuildCapacityTrendPointsFromHourlyFillsBuckets(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.Date(2026, 7, 10, 9, 30, 0, 0, time.UTC)
|
|
hourly := []*model.OpenFlareMetricHourly{
|
|
{
|
|
Hour: now.Add(-3 * time.Hour).Truncate(time.Hour),
|
|
AverageCPUUsagePercent: 42.5,
|
|
AverageMemoryUsagePercent: 61.2,
|
|
ReportedNodes: 1,
|
|
},
|
|
{
|
|
Hour: now.Truncate(time.Hour),
|
|
AverageCPUUsagePercent: 12.0,
|
|
AverageMemoryUsagePercent: 50.0,
|
|
ReportedNodes: 2,
|
|
},
|
|
}
|
|
|
|
points := BuildCapacityTrendPointsFromHourly(now, hourly)
|
|
if len(points) != observabilityTrendBuckets {
|
|
t.Fatalf("len = %d, want %d", len(points), observabilityTrendBuckets)
|
|
}
|
|
if points[len(points)-4].AverageCPUUsagePercent != 42.5 {
|
|
t.Fatalf("hour-3 cpu = %v, want 42.5", points[len(points)-4].AverageCPUUsagePercent)
|
|
}
|
|
if points[len(points)-1].ReportedNodes != 2 {
|
|
t.Fatalf("current hour reported_nodes = %d, want 2", points[len(points)-1].ReportedNodes)
|
|
}
|
|
}
|
|
|
|
func TestBuildNetworkTrendPointsUsesCounterDeltas(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.Date(2026, 7, 10, 9, 30, 0, 0, time.UTC)
|
|
base := now.Truncate(time.Hour)
|
|
snapshots := []*model.OpenFlareMetricSnapshot{
|
|
{NodeID: "n1", CapturedAt: base.Add(10 * time.Minute), NetworkRxBytes: 1000, NetworkTxBytes: 2000},
|
|
{NodeID: "n1", CapturedAt: base.Add(20 * time.Minute), NetworkRxBytes: 1500, NetworkTxBytes: 2600},
|
|
}
|
|
openrestyObs := []*model.OpenFlareNodeObservationOpenresty{
|
|
{NodeID: "n1", CapturedAt: base.Add(10 * time.Minute), OpenrestyRxBytes: 100, OpenrestyTxBytes: 200},
|
|
{NodeID: "n1", CapturedAt: base.Add(20 * time.Minute), OpenrestyRxBytes: 180, OpenrestyTxBytes: 250},
|
|
}
|
|
|
|
points := BuildNetworkTrendPoints(now, snapshots, openrestyObs)
|
|
current := points[len(points)-1]
|
|
if current.NetworkRxBytes != 500 {
|
|
t.Fatalf("network_rx_bytes = %d, want 500", current.NetworkRxBytes)
|
|
}
|
|
if current.NetworkTxBytes != 600 {
|
|
t.Fatalf("network_tx_bytes = %d, want 600", current.NetworkTxBytes)
|
|
}
|
|
if current.OpenrestyRxBytes != 80 {
|
|
t.Fatalf("openresty_rx_bytes = %d, want 80", current.OpenrestyRxBytes)
|
|
}
|
|
if current.OpenrestyTxBytes != 50 {
|
|
t.Fatalf("openresty_tx_bytes = %d, want 50", current.OpenrestyTxBytes)
|
|
}
|
|
}
|
|
|
|
func TestBuildDiskIOTrendPointsFromHourlyFillsBuckets(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.Date(2026, 7, 10, 9, 30, 0, 0, time.UTC)
|
|
hourly := []*model.OpenFlareMetricHourly{
|
|
{
|
|
Hour: now.Add(-1 * time.Hour).Truncate(time.Hour),
|
|
DiskReadBytes: 1024,
|
|
DiskWriteBytes: 2048,
|
|
ReportedNodes: 1,
|
|
},
|
|
}
|
|
|
|
points := BuildDiskIOTrendPointsFromHourly(now, hourly)
|
|
prev := points[len(points)-2]
|
|
if prev.DiskReadBytes != 1024 || prev.DiskWriteBytes != 2048 {
|
|
t.Fatalf("previous hour disk io = %#v, want read=1024 write=2048", prev)
|
|
}
|
|
}
|