@@ -22,6 +22,7 @@ package runtime
2222import (
2323 "errors"
2424 "fmt"
25+ "math"
2526 "strconv"
2627 "strings"
2728 "testing"
@@ -53,6 +54,25 @@ func isCgroupsV2(mounts []*types.Mount) (bool, error) {
5354 return false , errors .New ("Failed to find cgroup mount on /sys/fs/cgroup" )
5455}
5556
57+ // from https://github.com/opencontainers/cgroups/pull/20/files
58+ func convertCPUSharesToCgroupV2Value (cpuShares uint64 ) uint64 {
59+ // The value of 0 means "unset".
60+ if cpuShares == 0 {
61+ return 0
62+ }
63+ if cpuShares <= 2 {
64+ return 1
65+ }
66+ if cpuShares >= 262144 {
67+ return 10000
68+ }
69+ l := math .Log2 (float64 (cpuShares ))
70+ // Quadratic function which fits min, max, and default.
71+ exponent := (l * l + 125 * l )/ 612.0 - 7.0 / 34.0
72+
73+ return uint64 (math .Ceil (math .Pow (10 , exponent )))
74+ }
75+
5676// TestMustHaveCgroupConfigured verifies that the Linux cgroups are configured based on the specified
5777// resource limits and requests as delared by "MUST" in the runtime-contract.
5878func TestMustHaveCgroupConfigured (t * testing.T ) {
@@ -84,6 +104,9 @@ func TestMustHaveCgroupConfigured(t *testing.T) {
84104 "/sys/fs/cgroup/cpu.weight" : strconv .FormatInt (((((resources .Requests .Cpu ().MilliValue ()* 1024 / 1000 )- 2 )* 9999 )/ 262142 )+ 1 , 10 ),
85105 }
86106
107+ // cpu.weight conversion depends on runtime version, see https://github.com/kubernetes/kubernetes/issues/131216
108+ expectedCgroupsV2CpuWeightAlternativeFormula := strconv .FormatUint (convertCPUSharesToCgroupV2Value (uint64 (resources .Requests .Cpu ().MilliValue ()* 1024 / 1000 )), 10 )
109+
87110 cgroups := ri .Host .Cgroups
88111 cgroupV2 , err := isCgroupsV2 (ri .Host .Mounts )
89112 if err != nil {
@@ -122,6 +145,16 @@ func TestMustHaveCgroupConfigured(t *testing.T) {
122145 periodV2 = strings .Split (* cgroup .Value , " " )[1 ]
123146 }
124147
148+ // cpu.weight conversion depends on runtime version, let's try the new formula first,
149+ // if it fails, we fall back to the original formula we have in `expectedCgroups`
150+ if cgroup .Name == "/sys/fs/cgroup/cpu.weight" {
151+ if * cgroup .Value == expectedCgroupsV2CpuWeightAlternativeFormula {
152+ continue
153+ } else {
154+ t .Logf ("%s = %s, want: %s, falling back to the original cpu.weight formula" , cgroup .Name , * cgroup .Value , expectedCgroupsV2CpuWeightAlternativeFormula )
155+ }
156+ }
157+
125158 if _ , ok := expectedCgroups [cgroup .Name ]; ! ok {
126159 // Service returned a value we don't test
127160 t .Logf ("%v cgroup returned, but not validated" , cgroup .Name )
0 commit comments