Skip to content

Commit eb52ab6

Browse files
authored
Merge pull request containerd#10670 from jsturtevant/nano-calc-backport-1.7
[release/1.7] Cumulative stats can't decrease
2 parents b4aeec4 + 3658d5b commit eb52ab6

File tree

4 files changed

+48
-17
lines changed

4 files changed

+48
-17
lines changed

pkg/cri/sbserver/container_stats_list.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ func (c *criService) getUsageNanoCores(containerID string, isSandbox bool, curre
192192
return 0, nil
193193
}
194194

195+
// can't go backwards, this value might come in as 0 if the container was just removed
196+
if currentUsageCoreNanoSeconds < oldStats.UsageCoreNanoSeconds {
197+
return 0, nil
198+
}
199+
195200
newUsageNanoCores := uint64(float64(currentUsageCoreNanoSeconds-oldStats.UsageCoreNanoSeconds) /
196201
float64(nanoSeconds) * float64(time.Second/time.Nanosecond))
197202

pkg/cri/sbserver/container_stats_list_test.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,45 +35,56 @@ import (
3535
func TestContainerMetricsCPUNanoCoreUsage(t *testing.T) {
3636
c := newTestCRIService()
3737
timestamp := time.Now()
38-
secondAfterTimeStamp := timestamp.Add(time.Second)
39-
ID := "ID"
38+
tenSecondAftertimeStamp := timestamp.Add(time.Second * 10)
4039

4140
for desc, test := range map[string]struct {
41+
id string
42+
desc string
4243
firstCPUValue uint64
4344
secondCPUValue uint64
4445
expectedNanoCoreUsageFirst uint64
4546
expectedNanoCoreUsageSecond uint64
4647
}{
4748
"metrics": {
49+
id: "id1",
50+
desc: "metrics",
4851
firstCPUValue: 50,
4952
secondCPUValue: 500,
5053
expectedNanoCoreUsageFirst: 0,
51-
expectedNanoCoreUsageSecond: 450,
54+
expectedNanoCoreUsageSecond: 45,
55+
},
56+
"no metrics in second CPU sample": {
57+
id: "id2",
58+
desc: "metrics",
59+
firstCPUValue: 234235,
60+
secondCPUValue: 0,
61+
expectedNanoCoreUsageFirst: 0,
62+
expectedNanoCoreUsageSecond: 0,
5263
},
5364
} {
5465
t.Run(desc, func(t *testing.T) {
5566
container, err := containerstore.NewContainer(
56-
containerstore.Metadata{ID: ID},
67+
containerstore.Metadata{ID: test.id},
5768
)
5869
assert.NoError(t, err)
5970
assert.Nil(t, container.Stats)
6071
err = c.containerStore.Add(container)
6172
assert.NoError(t, err)
6273

63-
cpuUsage, err := c.getUsageNanoCores(ID, false, test.firstCPUValue, timestamp)
74+
cpuUsage, err := c.getUsageNanoCores(test.id, false, test.firstCPUValue, timestamp)
6475
assert.NoError(t, err)
6576

66-
container, err = c.containerStore.Get(ID)
77+
container, err = c.containerStore.Get(test.id)
6778
assert.NoError(t, err)
6879
assert.NotNil(t, container.Stats)
6980

7081
assert.Equal(t, test.expectedNanoCoreUsageFirst, cpuUsage)
7182

72-
cpuUsage, err = c.getUsageNanoCores(ID, false, test.secondCPUValue, secondAfterTimeStamp)
83+
cpuUsage, err = c.getUsageNanoCores(test.id, false, test.secondCPUValue, tenSecondAftertimeStamp)
7384
assert.NoError(t, err)
7485
assert.Equal(t, test.expectedNanoCoreUsageSecond, cpuUsage)
7586

76-
container, err = c.containerStore.Get(ID)
87+
container, err = c.containerStore.Get(test.id)
7788
assert.NoError(t, err)
7889
assert.NotNil(t, container.Stats)
7990
})

pkg/cri/server/container_stats_list.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ func (c *criService) getUsageNanoCores(containerID string, isSandbox bool, curre
122122
return 0, nil
123123
}
124124

125+
// can't go backwards, this value might come in as 0 if the container was just removed
126+
if currentUsageCoreNanoSeconds < oldStats.UsageCoreNanoSeconds {
127+
return 0, nil
128+
}
129+
125130
newUsageNanoCores := uint64(float64(currentUsageCoreNanoSeconds-oldStats.UsageCoreNanoSeconds) /
126131
float64(nanoSeconds) * float64(time.Second/time.Nanosecond))
127132

pkg/cri/server/container_stats_list_test.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,48 +27,58 @@ import (
2727
func TestContainerMetricsCPUNanoCoreUsage(t *testing.T) {
2828
c := newTestCRIService()
2929
timestamp := time.Now()
30-
secondAfterTimeStamp := timestamp.Add(time.Second)
31-
ID := "ID"
30+
tenSecondAftertimeStamp := timestamp.Add(time.Second * 10)
3231

3332
for desc, test := range map[string]struct {
33+
id string
34+
desc string
3435
firstCPUValue uint64
3536
secondCPUValue uint64
3637
expectedNanoCoreUsageFirst uint64
3738
expectedNanoCoreUsageSecond uint64
3839
}{
3940
"metrics": {
41+
id: "id1",
42+
desc: "metrics",
4043
firstCPUValue: 50,
4144
secondCPUValue: 500,
4245
expectedNanoCoreUsageFirst: 0,
43-
expectedNanoCoreUsageSecond: 450,
46+
expectedNanoCoreUsageSecond: 45,
47+
},
48+
"no metrics in second CPU sample": {
49+
id: "id2",
50+
desc: "metrics",
51+
firstCPUValue: 234235,
52+
secondCPUValue: 0,
53+
expectedNanoCoreUsageFirst: 0,
54+
expectedNanoCoreUsageSecond: 0,
4455
},
4556
} {
4657
t.Run(desc, func(t *testing.T) {
4758
container, err := containerstore.NewContainer(
48-
containerstore.Metadata{ID: ID},
59+
containerstore.Metadata{ID: test.id},
4960
)
5061
assert.NoError(t, err)
5162
assert.Nil(t, container.Stats)
5263
err = c.containerStore.Add(container)
5364
assert.NoError(t, err)
5465

55-
cpuUsage, err := c.getUsageNanoCores(ID, false, test.firstCPUValue, timestamp)
66+
cpuUsage, err := c.getUsageNanoCores(test.id, false, test.firstCPUValue, timestamp)
5667
assert.NoError(t, err)
5768

58-
container, err = c.containerStore.Get(ID)
69+
container, err = c.containerStore.Get(test.id)
5970
assert.NoError(t, err)
6071
assert.NotNil(t, container.Stats)
6172

6273
assert.Equal(t, test.expectedNanoCoreUsageFirst, cpuUsage)
6374

64-
cpuUsage, err = c.getUsageNanoCores(ID, false, test.secondCPUValue, secondAfterTimeStamp)
75+
cpuUsage, err = c.getUsageNanoCores(test.id, false, test.secondCPUValue, tenSecondAftertimeStamp)
6576
assert.NoError(t, err)
6677
assert.Equal(t, test.expectedNanoCoreUsageSecond, cpuUsage)
6778

68-
container, err = c.containerStore.Get(ID)
79+
container, err = c.containerStore.Get(test.id)
6980
assert.NoError(t, err)
7081
assert.NotNil(t, container.Stats)
7182
})
7283
}
73-
7484
}

0 commit comments

Comments
 (0)