All checks were successful
ci / build (push) Successful in 34s
- Extend StatSummary with p99, p75, p50 percentiles (in addition to peak, p95, avg) - Add ContainerSummary type for per-container CPU cores and memory bytes stats - Track container metrics from Cgroups map in Accumulator - Include containers array in RunSummary sent to receiver Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
533 lines
15 KiB
Go
533 lines
15 KiB
Go
// ABOUTME: Tests for the summary accumulator that tracks metrics across a run.
|
|
// ABOUTME: Validates stats computation (peak/avg/P95), process peak tracking, and edge cases.
|
|
package summary
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"edp.buildth.ing/DevFW-CICD/forgejo-runner-resource-collector/internal/metrics"
|
|
)
|
|
|
|
func TestAccumulator_NoSamples(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
result := acc.Summarize()
|
|
if result != nil {
|
|
t.Errorf("expected nil summary for no samples, got %+v", result)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_SingleSample(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{TotalPercent: 42.5},
|
|
Memory: metrics.MemoryMetrics{
|
|
UsedBytes: 1000,
|
|
UsedPercent: 50.0,
|
|
},
|
|
})
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// With a single sample, peak=avg=p95
|
|
if s.CPUTotal.Peak != 42.5 {
|
|
t.Errorf("CPU peak: got %f, want 42.5", s.CPUTotal.Peak)
|
|
}
|
|
if s.CPUTotal.Avg != 42.5 {
|
|
t.Errorf("CPU avg: got %f, want 42.5", s.CPUTotal.Avg)
|
|
}
|
|
if s.CPUTotal.P95 != 42.5 {
|
|
t.Errorf("CPU p95: got %f, want 42.5", s.CPUTotal.P95)
|
|
}
|
|
if s.MemUsedBytes.Peak != 1000 {
|
|
t.Errorf("MemUsedBytes peak: got %f, want 1000", s.MemUsedBytes.Peak)
|
|
}
|
|
if s.MemUsedPercent.Peak != 50.0 {
|
|
t.Errorf("MemUsedPercent peak: got %f, want 50.0", s.MemUsedPercent.Peak)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_Stats(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
cpuValues := []float64{10, 20, 30, 40, 50}
|
|
for i, v := range cpuValues {
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, i, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{TotalPercent: v},
|
|
Memory: metrics.MemoryMetrics{
|
|
UsedBytes: uint64(v * 100),
|
|
UsedPercent: v,
|
|
},
|
|
})
|
|
}
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// Peak = max = 50
|
|
if s.CPUTotal.Peak != 50 {
|
|
t.Errorf("CPU peak: got %f, want 50", s.CPUTotal.Peak)
|
|
}
|
|
// Avg = (10+20+30+40+50)/5 = 30
|
|
if s.CPUTotal.Avg != 30 {
|
|
t.Errorf("CPU avg: got %f, want 30", s.CPUTotal.Avg)
|
|
}
|
|
// P95: sorted=[10,20,30,40,50], index=int(4*0.95)=int(3.8)=3, value=40
|
|
if s.CPUTotal.P95 != 40 {
|
|
t.Errorf("CPU p95: got %f, want 40", s.CPUTotal.P95)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_P95_LargerDataset(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
// 20 values: 1, 2, 3, ..., 20
|
|
for i := 1; i <= 20; i++ {
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, i, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{TotalPercent: float64(i)},
|
|
Memory: metrics.MemoryMetrics{},
|
|
})
|
|
}
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// P95: sorted=[1..20], index=int(19*0.95)=int(18.05)=18, value=19
|
|
if s.CPUTotal.P95 != 19 {
|
|
t.Errorf("CPU p95: got %f, want 19", s.CPUTotal.P95)
|
|
}
|
|
// Avg = (1+2+...+20)/20 = 210/20 = 10.5
|
|
if s.CPUTotal.Avg != 10.5 {
|
|
t.Errorf("CPU avg: got %f, want 10.5", s.CPUTotal.Avg)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_MemoryStats(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
memBytes := []uint64{1000, 2000, 3000, 4000, 5000}
|
|
memPercent := []float64{10, 20, 30, 40, 50}
|
|
|
|
for i := range memBytes {
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, i, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{TotalPercent: 0},
|
|
Memory: metrics.MemoryMetrics{
|
|
UsedBytes: memBytes[i],
|
|
UsedPercent: memPercent[i],
|
|
},
|
|
})
|
|
}
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// MemUsedBytes: peak=5000, avg=3000, p95=4000
|
|
if s.MemUsedBytes.Peak != 5000 {
|
|
t.Errorf("MemUsedBytes peak: got %f, want 5000", s.MemUsedBytes.Peak)
|
|
}
|
|
if s.MemUsedBytes.Avg != 3000 {
|
|
t.Errorf("MemUsedBytes avg: got %f, want 3000", s.MemUsedBytes.Avg)
|
|
}
|
|
if s.MemUsedBytes.P95 != 4000 {
|
|
t.Errorf("MemUsedBytes p95: got %f, want 4000", s.MemUsedBytes.P95)
|
|
}
|
|
|
|
// MemUsedPercent: peak=50, avg=30, p95=40
|
|
if s.MemUsedPercent.Peak != 50 {
|
|
t.Errorf("MemUsedPercent peak: got %f, want 50", s.MemUsedPercent.Peak)
|
|
}
|
|
if s.MemUsedPercent.Avg != 30 {
|
|
t.Errorf("MemUsedPercent avg: got %f, want 30", s.MemUsedPercent.Avg)
|
|
}
|
|
if s.MemUsedPercent.P95 != 40 {
|
|
t.Errorf("MemUsedPercent p95: got %f, want 40", s.MemUsedPercent.P95)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_ProcessPeaks(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
|
|
// Same PID across two samples; peaks should be retained
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
TopCPU: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "a", CPUPercent: 10, MemRSS: 100},
|
|
},
|
|
TopMemory: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "a", CPUPercent: 10, MemRSS: 100},
|
|
},
|
|
})
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 1, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
TopCPU: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "a", CPUPercent: 20, MemRSS: 50},
|
|
},
|
|
TopMemory: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "a", CPUPercent: 5, MemRSS: 200},
|
|
},
|
|
})
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// Should find PID 1 with peak CPU=20, peak mem=200
|
|
found := false
|
|
for _, p := range s.TopCPUProcesses {
|
|
if p.PID == 1 {
|
|
found = true
|
|
if p.PeakCPU != 20 {
|
|
t.Errorf("PeakCPU: got %f, want 20", p.PeakCPU)
|
|
}
|
|
if p.PeakMem != 200 {
|
|
t.Errorf("PeakMem: got %d, want 200", p.PeakMem)
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
t.Error("PID 1 not found in TopCPUProcesses")
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_ProcessPeaks_TopN(t *testing.T) {
|
|
acc := NewAccumulator(2) // Only top 2
|
|
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
TopCPU: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "low", CPUPercent: 10, MemRSS: 100},
|
|
{PID: 2, Name: "mid", CPUPercent: 50, MemRSS: 500},
|
|
{PID: 3, Name: "high", CPUPercent: 90, MemRSS: 900},
|
|
},
|
|
TopMemory: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "low", CPUPercent: 10, MemRSS: 100},
|
|
{PID: 2, Name: "mid", CPUPercent: 50, MemRSS: 500},
|
|
{PID: 3, Name: "high", CPUPercent: 90, MemRSS: 900},
|
|
},
|
|
})
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// TopCPUProcesses should have at most 2 entries, sorted by PeakCPU descending
|
|
if len(s.TopCPUProcesses) != 2 {
|
|
t.Fatalf("TopCPUProcesses length: got %d, want 2", len(s.TopCPUProcesses))
|
|
}
|
|
if s.TopCPUProcesses[0].PeakCPU != 90 {
|
|
t.Errorf("TopCPU[0] PeakCPU: got %f, want 90", s.TopCPUProcesses[0].PeakCPU)
|
|
}
|
|
if s.TopCPUProcesses[1].PeakCPU != 50 {
|
|
t.Errorf("TopCPU[1] PeakCPU: got %f, want 50", s.TopCPUProcesses[1].PeakCPU)
|
|
}
|
|
|
|
// TopMemProcesses should have at most 2 entries, sorted by PeakMem descending
|
|
if len(s.TopMemProcesses) != 2 {
|
|
t.Fatalf("TopMemProcesses length: got %d, want 2", len(s.TopMemProcesses))
|
|
}
|
|
if s.TopMemProcesses[0].PeakMem != 900 {
|
|
t.Errorf("TopMem[0] PeakMem: got %d, want 900", s.TopMemProcesses[0].PeakMem)
|
|
}
|
|
if s.TopMemProcesses[1].PeakMem != 500 {
|
|
t.Errorf("TopMem[1] PeakMem: got %d, want 500", s.TopMemProcesses[1].PeakMem)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_ProcessPeaks_Dedup(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
|
|
// A process appears in both TopCPU and TopMemory
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
TopCPU: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "proc", CPUPercent: 80, MemRSS: 100},
|
|
},
|
|
TopMemory: []metrics.ProcessMetrics{
|
|
{PID: 1, Name: "proc", CPUPercent: 30, MemRSS: 500},
|
|
},
|
|
})
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// The internal process map should have merged the peaks
|
|
// PeakCPU should be 80 (from TopCPU), PeakMem should be 500 (from TopMemory)
|
|
for _, p := range s.TopCPUProcesses {
|
|
if p.PID == 1 {
|
|
if p.PeakCPU != 80 {
|
|
t.Errorf("PeakCPU: got %f, want 80", p.PeakCPU)
|
|
}
|
|
if p.PeakMem != 500 {
|
|
t.Errorf("PeakMem: got %d, want 500", p.PeakMem)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_SampleCount(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
if acc.SampleCount() != 0 {
|
|
t.Errorf("initial SampleCount: got %d, want 0", acc.SampleCount())
|
|
}
|
|
|
|
for i := 0; i < 3; i++ {
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, i, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
})
|
|
}
|
|
|
|
if acc.SampleCount() != 3 {
|
|
t.Errorf("SampleCount after 3 adds: got %d, want 3", acc.SampleCount())
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_Duration(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
start := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
end := time.Date(2025, 1, 1, 0, 1, 0, 0, time.UTC) // 60 seconds later
|
|
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: start,
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
})
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: end,
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
})
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
if !s.StartTime.Equal(start) {
|
|
t.Errorf("StartTime: got %v, want %v", s.StartTime, start)
|
|
}
|
|
if s.DurationSeconds != 60 {
|
|
t.Errorf("DurationSeconds: got %f, want 60", s.DurationSeconds)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_AllPercentiles(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
// 20 values: 1, 2, 3, ..., 20
|
|
for i := 1; i <= 20; i++ {
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, i, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{TotalPercent: float64(i)},
|
|
Memory: metrics.MemoryMetrics{},
|
|
})
|
|
}
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// Peak = 20
|
|
if s.CPUTotal.Peak != 20 {
|
|
t.Errorf("CPU peak: got %f, want 20", s.CPUTotal.Peak)
|
|
}
|
|
// P99: index=int(19*0.99)=int(18.81)=18, value=19
|
|
if s.CPUTotal.P99 != 19 {
|
|
t.Errorf("CPU p99: got %f, want 19", s.CPUTotal.P99)
|
|
}
|
|
// P95: index=int(19*0.95)=int(18.05)=18, value=19
|
|
if s.CPUTotal.P95 != 19 {
|
|
t.Errorf("CPU p95: got %f, want 19", s.CPUTotal.P95)
|
|
}
|
|
// P75: index=int(19*0.75)=int(14.25)=14, value=15
|
|
if s.CPUTotal.P75 != 15 {
|
|
t.Errorf("CPU p75: got %f, want 15", s.CPUTotal.P75)
|
|
}
|
|
// P50: index=int(19*0.50)=int(9.5)=9, value=10
|
|
if s.CPUTotal.P50 != 10 {
|
|
t.Errorf("CPU p50: got %f, want 10", s.CPUTotal.P50)
|
|
}
|
|
// Avg = (1+2+...+20)/20 = 210/20 = 10.5
|
|
if s.CPUTotal.Avg != 10.5 {
|
|
t.Errorf("CPU avg: got %f, want 10.5", s.CPUTotal.Avg)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_ContainerMetrics(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
|
|
// Add samples with container metrics
|
|
for i := 1; i <= 5; i++ {
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, i, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{TotalPercent: float64(i * 10)},
|
|
Memory: metrics.MemoryMetrics{},
|
|
Cgroups: map[string]*metrics.CgroupMetrics{
|
|
"container-a": {
|
|
Name: "container-a",
|
|
CPU: metrics.CgroupCPUMetrics{UsedCores: float64(i)},
|
|
Memory: metrics.CgroupMemoryMetrics{
|
|
TotalRSSBytes: uint64(i * 1000),
|
|
},
|
|
},
|
|
"container-b": {
|
|
Name: "container-b",
|
|
CPU: metrics.CgroupCPUMetrics{UsedCores: float64(i * 2)},
|
|
Memory: metrics.CgroupMemoryMetrics{
|
|
TotalRSSBytes: uint64(i * 2000),
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// Should have 2 containers
|
|
if len(s.Containers) != 2 {
|
|
t.Fatalf("Containers length: got %d, want 2", len(s.Containers))
|
|
}
|
|
|
|
// Containers should be sorted by name
|
|
if s.Containers[0].Name != "container-a" {
|
|
t.Errorf("Containers[0].Name: got %s, want container-a", s.Containers[0].Name)
|
|
}
|
|
if s.Containers[1].Name != "container-b" {
|
|
t.Errorf("Containers[1].Name: got %s, want container-b", s.Containers[1].Name)
|
|
}
|
|
|
|
// Container A: CPU cores [1,2,3,4,5], peak=5, avg=3
|
|
containerA := s.Containers[0]
|
|
if containerA.CPUCores.Peak != 5 {
|
|
t.Errorf("container-a CPUCores.Peak: got %f, want 5", containerA.CPUCores.Peak)
|
|
}
|
|
if containerA.CPUCores.Avg != 3 {
|
|
t.Errorf("container-a CPUCores.Avg: got %f, want 3", containerA.CPUCores.Avg)
|
|
}
|
|
// Memory bytes [1000,2000,3000,4000,5000], peak=5000, avg=3000
|
|
if containerA.MemoryBytes.Peak != 5000 {
|
|
t.Errorf("container-a MemoryBytes.Peak: got %f, want 5000", containerA.MemoryBytes.Peak)
|
|
}
|
|
if containerA.MemoryBytes.Avg != 3000 {
|
|
t.Errorf("container-a MemoryBytes.Avg: got %f, want 3000", containerA.MemoryBytes.Avg)
|
|
}
|
|
|
|
// Container B: CPU cores [2,4,6,8,10], peak=10, avg=6
|
|
containerB := s.Containers[1]
|
|
if containerB.CPUCores.Peak != 10 {
|
|
t.Errorf("container-b CPUCores.Peak: got %f, want 10", containerB.CPUCores.Peak)
|
|
}
|
|
if containerB.CPUCores.Avg != 6 {
|
|
t.Errorf("container-b CPUCores.Avg: got %f, want 6", containerB.CPUCores.Avg)
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_ContainerMetrics_NoContainers(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{TotalPercent: 50},
|
|
Memory: metrics.MemoryMetrics{},
|
|
Cgroups: nil, // No containers
|
|
})
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
if len(s.Containers) != 0 {
|
|
t.Errorf("Containers length: got %d, want 0", len(s.Containers))
|
|
}
|
|
}
|
|
|
|
func TestAccumulator_ContainerMetrics_PartialSamples(t *testing.T) {
|
|
acc := NewAccumulator(5)
|
|
|
|
// First sample: only container-a
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 1, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
Cgroups: map[string]*metrics.CgroupMetrics{
|
|
"container-a": {
|
|
Name: "container-a",
|
|
CPU: metrics.CgroupCPUMetrics{UsedCores: 1},
|
|
Memory: metrics.CgroupMemoryMetrics{TotalRSSBytes: 1000},
|
|
},
|
|
},
|
|
})
|
|
|
|
// Second sample: both containers
|
|
acc.Add(&metrics.SystemMetrics{
|
|
Timestamp: time.Date(2025, 1, 1, 0, 0, 2, 0, time.UTC),
|
|
CPU: metrics.CPUMetrics{},
|
|
Memory: metrics.MemoryMetrics{},
|
|
Cgroups: map[string]*metrics.CgroupMetrics{
|
|
"container-a": {
|
|
Name: "container-a",
|
|
CPU: metrics.CgroupCPUMetrics{UsedCores: 2},
|
|
Memory: metrics.CgroupMemoryMetrics{TotalRSSBytes: 2000},
|
|
},
|
|
"container-b": {
|
|
Name: "container-b",
|
|
CPU: metrics.CgroupCPUMetrics{UsedCores: 5},
|
|
Memory: metrics.CgroupMemoryMetrics{TotalRSSBytes: 5000},
|
|
},
|
|
},
|
|
})
|
|
|
|
s := acc.Summarize()
|
|
if s == nil {
|
|
t.Fatal("expected non-nil summary")
|
|
}
|
|
|
|
// Should have 2 containers
|
|
if len(s.Containers) != 2 {
|
|
t.Fatalf("Containers length: got %d, want 2", len(s.Containers))
|
|
}
|
|
|
|
// Container A: 2 samples [1,2]
|
|
containerA := s.Containers[0]
|
|
if containerA.CPUCores.Peak != 2 {
|
|
t.Errorf("container-a CPUCores.Peak: got %f, want 2", containerA.CPUCores.Peak)
|
|
}
|
|
if containerA.CPUCores.Avg != 1.5 {
|
|
t.Errorf("container-a CPUCores.Avg: got %f, want 1.5", containerA.CPUCores.Avg)
|
|
}
|
|
|
|
// Container B: 1 sample [5]
|
|
containerB := s.Containers[1]
|
|
if containerB.CPUCores.Peak != 5 {
|
|
t.Errorf("container-b CPUCores.Peak: got %f, want 5", containerB.CPUCores.Peak)
|
|
}
|
|
if containerB.CPUCores.Avg != 5 {
|
|
t.Errorf("container-b CPUCores.Avg: got %f, want 5", containerB.CPUCores.Avg)
|
|
}
|
|
}
|