diff --git a/pkg/storage/types.go b/pkg/storage/types.go index 9d1b9e7f3..be024f33a 100644 --- a/pkg/storage/types.go +++ b/pkg/storage/types.go @@ -65,6 +65,9 @@ type MetricsPoint struct { } func resourceUsage(last, prev MetricsPoint) (corev1.ResourceList, api.TimeInfo, error) { + if last.StartTime.Before(prev.StartTime) { + return corev1.ResourceList{}, api.TimeInfo{}, fmt.Errorf("unexpected decrease in startTime of node/container") + } if last.CumulativeCpuUsed < prev.CumulativeCpuUsed { return corev1.ResourceList{}, api.TimeInfo{}, fmt.Errorf("unexpected decrease in cumulative CPU usage value") } diff --git a/pkg/storage/types_test.go b/pkg/storage/types_test.go index be2d14bcd..9b02fd19e 100644 --- a/pkg/storage/types_test.go +++ b/pkg/storage/types_test.go @@ -16,9 +16,13 @@ package storage import ( "math" + "reflect" "testing" + "time" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + "sigs.k8s.io/metrics-server/pkg/api" ) func TestUint64Quantity(t *testing.T) { @@ -41,3 +45,55 @@ func TestUint64Quantity(t *testing.T) { }) } } + +func Test_resourceUsage(t *testing.T) { + start := time.Now() + tcs := []struct { + name string + last MetricsPoint + prev MetricsPoint + wantResourceList v1.ResourceList + wantTimeInfo api.TimeInfo + wantErr bool + }{ + { + name: "get resource usage successfully", + last: newMetricsPoint(start, start.Add(20*time.Millisecond), 500, 600), + prev: newMetricsPoint(start, start.Add(10*time.Millisecond), 300, 400), + wantResourceList: v1.ResourceList{v1.ResourceCPU: uint64Quantity(uint64(20000), resource.DecimalSI, -9), + v1.ResourceMemory: uint64Quantity(600, resource.BinarySI, 0)}, + wantTimeInfo: api.TimeInfo{Timestamp: start.Add(20 * time.Millisecond), Window: 10 * time.Millisecond}, + }, + { + name: "get resource usage failed because of unexpected decrease in startTime", + last: newMetricsPoint(start, start.Add(20*time.Millisecond), 500, 600), + prev: newMetricsPoint(start.Add(20*time.Millisecond), start.Add(10*time.Millisecond), 300, 400), + wantResourceList: v1.ResourceList{}, + wantTimeInfo: api.TimeInfo{}, + wantErr: true, + }, + { + name: "get resource usage failed because of unexpected decrease in cumulative CPU usage value", + last: newMetricsPoint(start, start.Add(20*time.Millisecond), 100, 600), + prev: newMetricsPoint(start, start.Add(10*time.Millisecond), 300, 400), + wantResourceList: v1.ResourceList{}, + wantTimeInfo: api.TimeInfo{}, + wantErr: true, + }, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + resourceList, timeInfo, err := resourceUsage(tc.last, tc.prev) + if (err != nil) != tc.wantErr { + t.Errorf("resourceUsage() error = %v, wantErr %v", err, tc.wantErr) + return + } + if !reflect.DeepEqual(resourceList, tc.wantResourceList) { + t.Errorf("resourceUsage() resourceList = %v, want %v", resourceList, tc.wantResourceList) + } + if !reflect.DeepEqual(timeInfo, tc.wantTimeInfo) { + t.Errorf("resourceUsage() timeInfo = %v, want %v", timeInfo, tc.wantTimeInfo) + } + }) + } +}