diff --git a/internal/cri/server/container_stats_list.go b/internal/cri/server/container_stats_list.go index 476d4b999e05..eabcae7fe624 100644 --- a/internal/cri/server/container_stats_list.go +++ b/internal/cri/server/container_stats_list.go @@ -224,6 +224,11 @@ func (c *criService) getUsageNanoCores(containerID string, isSandbox bool, curre return 0, nil } + // can't go backwards, this value might come in as 0 if the container was just removed + if currentUsageCoreNanoSeconds < oldStats.UsageCoreNanoSeconds { + return 0, nil + } + newUsageNanoCores := uint64(float64(currentUsageCoreNanoSeconds-oldStats.UsageCoreNanoSeconds) / float64(nanoSeconds) * float64(time.Second/time.Nanosecond)) diff --git a/internal/cri/server/container_stats_list_test.go b/internal/cri/server/container_stats_list_test.go index 5154d1183d3a..00bd719b08fe 100644 --- a/internal/cri/server/container_stats_list_test.go +++ b/internal/cri/server/container_stats_list_test.go @@ -35,10 +35,10 @@ import ( func TestContainerMetricsCPUNanoCoreUsage(t *testing.T) { c := newTestCRIService() timestamp := time.Now() - secondAfterTimeStamp := timestamp.Add(time.Second) - ID := "ID" + tenSecondAftertimeStamp := timestamp.Add(time.Second * 10) for _, test := range []struct { + id string desc string firstCPUValue uint64 secondCPUValue uint64 @@ -46,37 +46,46 @@ func TestContainerMetricsCPUNanoCoreUsage(t *testing.T) { expectedNanoCoreUsageSecond uint64 }{ { + id: "id1", desc: "metrics", firstCPUValue: 50, secondCPUValue: 500, expectedNanoCoreUsageFirst: 0, - expectedNanoCoreUsageSecond: 450, + expectedNanoCoreUsageSecond: 45, + }, + { + id: "id2", + desc: "metrics", + firstCPUValue: 234235, + secondCPUValue: 0, + expectedNanoCoreUsageFirst: 0, + expectedNanoCoreUsageSecond: 0, }, } { test := test t.Run(test.desc, func(t *testing.T) { container, err := containerstore.NewContainer( - containerstore.Metadata{ID: ID}, + containerstore.Metadata{ID: test.id}, ) assert.NoError(t, err) assert.Nil(t, container.Stats) err = c.containerStore.Add(container) assert.NoError(t, err) - cpuUsage, err := c.getUsageNanoCores(ID, false, test.firstCPUValue, timestamp) + cpuUsage, err := c.getUsageNanoCores(test.id, false, test.firstCPUValue, timestamp) assert.NoError(t, err) - container, err = c.containerStore.Get(ID) + container, err = c.containerStore.Get(test.id) assert.NoError(t, err) assert.NotNil(t, container.Stats) assert.Equal(t, test.expectedNanoCoreUsageFirst, cpuUsage) - cpuUsage, err = c.getUsageNanoCores(ID, false, test.secondCPUValue, secondAfterTimeStamp) + cpuUsage, err = c.getUsageNanoCores(test.id, false, test.secondCPUValue, tenSecondAftertimeStamp) assert.NoError(t, err) assert.Equal(t, test.expectedNanoCoreUsageSecond, cpuUsage) - container, err = c.containerStore.Get(ID) + container, err = c.containerStore.Get(test.id) assert.NoError(t, err) assert.NotNil(t, container.Stats) })